Makes selection of multiple roads based on given condition
// ==UserScript== // @name WME Road Selector // @description Makes selection of multiple roads based on given condition // @match https://www.waze.com/*editor* // @match https://beta.waze.com/*editor* // @version 1.50.3 // @copyright 2014-2024, pvo11 (HTML design by bures) // @namespace https://greasyfork.org/scripts/3462-wme-road-selector // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAAEEfUpiAAAAB3RJTUUH4AsBDQ0yYF1byAAAAAlwSFlzAAALEQAACxEBf2RfkQAAAARnQU1BAACxjwv8YQUAAAKQSURBVHjazVe/TxRBFH57hwngXTyEBCQSExsvkT/AktLe1oLOAhoqryBAYUJrAbWY8CeYWGoCiZYWGGqzGDFZ5EgWcol7LO/b2bmbnf01dzf++JI3s7cz33tv3rx5O0dUhJDR/+W5Yc6IBieTkgRG8kd7kzblRCdXi8BqiqHPrcT9Vtwvkx2UrWTx/DQMEC7PfeNksI+5fRRFbWbBSQ967kGezW7e4AdsT+3spCC8RvE3W/5jlk9R5IeNHdC6bIfx7xfOAAquEbqGU6F2eC3fzpkQj2NrB1nDY4VEoibLYXrDdAUIDtERHhUXgyKihEzX52h2bjfIuztf7l2B29ss71keDE7+K8jwcJA80FN5mYP8tmJI3kaHIAfT9+XbPTRmCoiW0KyM16jKfc3pO26q4GW03rMTqv/6Tr4orm2zGHjuLLen2luf118vV5Ak15h0qU9xRiHnKzAk9xV4LoLboXT+F5IBuQsRea5SVccelpFVBWOL1Vv0Y+qemigbZWRVAR11f0f9+tWFfPXZRIGMAarsVmLEoJgkMVLJ/ocYcJlGkUAqrMeip5XP0uLw7v4ZB8TH4YtqGKnZ4cOvfMsAFIImO/LTtJqYYkcaR1qHnNJI7XP+0CC9lTLWYHmNB9sO9FIfx2K340fPXRLHw0/eMT+isbcFov5AadNgdvQ5seNAtuFDljWWZyxPlBXvseFvKn14B/INPzWpgcM7YMlwsQPiOOG6tETiyCC53rHs2zKc7UBWTc7GyIYl+sdQ3F16xnGHwTnG+W1N1HXevg3jSQfiuw+AIoI7EIC6+mryTuIupM4dFep/zFQZxV07oFAvIL0yajcCMwtfuR0nsQ1BZInrt2IcZW2V503ZMv5f4AazFTZB3RZIZwAAAABJRU5ErkJggg== // ==/UserScript== var StringOps = { 0: "=", 1: "!=", 2: "contains", 3: "! contains", 4: "~" }; var IntegerOps = { 0: "=", 1: "!=", 2: ">", 3: ">=", 4: "<", 5: "<=" }; var EqualOps = { 0: "=", 1: "!=" }; var RestrDirs = { 0: "---", 1: "Two way", 2: "A > B", 3: "B > A" }; var RestrLanes = { 0: "---", 1: "Entire", 2: "Left", 3: "Middle", 4: "Right" }; var RestrCars = { 0: "---", 9: "None", 4: "Bus", 3: "Express", 5: "Fast", 2: "HOT", 1: "HOV" }; var RestrCarsOrder = [0, 9, 4, 3, 5, 2, 1]; var RestrTypes = { 0: "---", 1: "allowed for", 2: "toll free for", 3: "prohibited for All vehicles", 4: "prohibited for Only" } var RestrSelOps = { 0: "---", 1: "ANY", 2: "ALL" } var RestrCarTypes = { 0: "BUS", 1: "CAV", 2: "CLEAN_FUEL", 3: "EV", 4: "HAZARDOUS_MATERIALS", 5: "HYBRID", 6: "MOTORCYCLE", 7: "PRIVATE", 8: "PUBLIC_TRANSPORTATION", 9: "RV", 10: "TAXI", 11: "TOWING_VEHICLE", 12: "TRUCK" } var RestrCarTypesN = { 0: 288, 1: 1792, 2: 1840, 3: 1808, 4: 1536, 5: 1824, 6: 1024, 7: 1280, 8: 256, 9: 512, 10: 272, 11: 768, 12: 0 } var Directions = { 0: "Two way (=)", 1: "One way (A›B)", 2: "One way (B›A)", 3: "Unknown" }; var uOpenLayers; var uWaze; function populateOptions(sel, tbl) { var selId = getId(sel); for (var id in tbl) { var txt = tbl[id]; var usrOption = document.createElement('option'); var usrText = document.createTextNode(txt); if (id === 0) { usrOption.setAttribute('selected',true); } usrOption.setAttribute('value',id); usrOption.appendChild(usrText); selId.appendChild(usrOption); } } function populateLocalizedOptions(sel, tbl, loc) { var selId = getId(sel); for (var id in tbl) { var txt = tbl[id]; var usrOption = document.createElement('option'); var usrText = document.createTextNode(loc[txt]); if (id === 0) { usrOption.setAttribute('selected',true); } usrOption.setAttribute('value',id); usrOption.appendChild(usrText); selId.appendChild(usrOption); } } function populateOrderedOptions(sel, tbl, ord) { var selId = getId(sel); for (var i = 0; i < ord.length; i++) { var id = ord[i]; var txt = tbl[id]; var usrOption = document.createElement('option'); var usrText = document.createTextNode(txt); if (id === 0) { usrOption.setAttribute('selected',true); } usrOption.setAttribute('value',id); usrOption.appendChild(usrText); selId.appendChild(usrOption); } } function populateObjectOptions(sel, obj) { var selId = getId(sel); var usrOption = document.createElement('option'); var usrText = document.createTextNode("---"); usrOption.setAttribute('selected',true); usrOption.setAttribute('value','-'); usrOption.appendChild(usrText); selId.appendChild(usrOption); for (var id in obj) { usrOption = document.createElement('option'); usrText = document.createTextNode(obj[id]); usrOption.setAttribute('value',id); usrOption.appendChild(usrText); selId.appendChild(usrOption); } } var DirOps = { 0: "none", 1: "any", 2: "both", 3: "A›B", 4: "B›A", 5: "hidden", 6: "unverified", 7: "only one" }; function populateDirOps(sel, unver) { var selectDirOp = getId(sel); for (var id in DirOps) { if (unver || id !== '6') { var txt = DirOps[id]; var usrOption = document.createElement('option'); var usrText = document.createTextNode(txt); if (id === 0) { usrOption.setAttribute('selected',true); } usrOption.setAttribute('value',id); usrOption.appendChild(usrText); selectDirOp.appendChild(usrOption); } } } var Countries = {}; function populateCountries() { var selectCountry = getId("selRSCountry"); for (var countryID in uWaze.model.countries.objects) { if (typeof Countries[countryID] === 'undefined') { Countries[countryID] = uWaze.model.countries.getObjectById(countryID).attributes.name; var txt = Countries[countryID]; var usrOption = document.createElement('option'); var usrText = document.createTextNode(txt); usrOption.setAttribute('value',countryID); usrOption.appendChild(usrText); selectCountry.appendChild(usrOption); } } } var RoadTypeCategories = { 101: "highways", 102: "streets", 103: "other_drivable", 104: "non_drivable", }; var RoadTypesOrder = [101, 3, 6, 7, 4, 102, 2, 1, 22, 103, 8, 20, 17, 15, 104, 5, 10, 16, 18, 19]; function populateRoadTypes(sel) { var selectRoadType = getId(sel); for (var i = 0; i < RoadTypesOrder.length; i++) { var id = RoadTypesOrder[i]; var txt if (id > 100) { txt = "-- " + I18n.translations[I18n.currentLocale()].segment.categories[RoadTypeCategories[id]] + " --"; } else { txt = I18n.translations[I18n.currentLocale()].segment.road_types[id]; } var usrOption = document.createElement('option'); var usrText = document.createTextNode(txt); if (id == 1) { usrOption.setAttribute('selected',true); } if (id > 100) { usrOption.setAttribute('disabled',true); usrOption.setAttribute('style','font-weight: bold'); } usrOption.setAttribute('value',id); usrOption.appendChild(usrText); selectRoadType.appendChild(usrOption); } } function populateElevations(sel) { var selectElevation = getId(sel); for (var id = 9; id >= -5; id--) { var txt; if (id === 0) { txt = "Ground"; } else { txt = String(id); } var usrOption = document.createElement('option'); var usrText = document.createTextNode(txt); if (id === 0) { usrOption.setAttribute('selected',true); } usrOption.setAttribute('value',id); usrOption.appendChild(usrText); selectElevation.appendChild(usrOption); } } function populateLocks(sel) { var selectLock = getId(sel); for (var id = 1; id <= 6; id++) { var txt = String(id); var usrOption = document.createElement('option'); var usrText = document.createTextNode(txt); if (id === 1) { usrOption.setAttribute('selected',true); } usrOption.setAttribute('value',id); usrOption.appendChild(usrText); selectLock.appendChild(usrOption); } } var milesConst = 1.609344; function km2miles(km) { return Math.round(km / milesConst); } function miles2km(m) { return Math.round(m * milesConst); } function decimalRound(value, exp) { if (typeof exp === 'undefined' || +exp === 0) { return Math.round(value); } value = +value; exp = +exp; if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) { return NaN; } value = value.toString().split('e'); value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp))); value = value.toString().split('e'); return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)); } var ExprStatus = 0; var ExprTree = {}; var BktTrees = {}; var BktOps = {}; var BktCount = 0; var hasStates; var speedInMiles; var hasSubcriptions; var Subscriptions = {}; function getSubscriptions() { for (var countryID in uWaze.model.countries.objects) { for (var subscr in uWaze.model.countries.getObjectById(countryID).restrictionSubscriptions) { hasSubcriptions = true; Subscriptions[subscr] = uWaze.model.countries.getObjectById(countryID).restrictionSubscriptions[subscr]; } } } function checkExpr(tree, segment) { if (typeof (tree.type) === 'undefined') { return false; } var result; switch (tree.type) { case "Country": var sid = segment.attributes.primaryStreetID; if (typeof(sid) === 'undefined' || sid === null) { result = false; } else { var street = uWaze.model.streets.getObjectById(sid); if (typeof(street) === 'undefined') { result = false; } else { var countryID = uWaze.model.cities.objects[street.attributes.cityID].attributes.countryID; if (tree.op === "0") { result = tree.id == countryID; } else { result = tree.id != countryID; } } } break; case "State": case "XState": var sid = segment.attributes.primaryStreetID; if (typeof(sid) === 'undefined' || sid === null) { result = false; } else { var street = uWaze.model.streets.getObjectById(sid); if (typeof(street) === 'undefined') { result = false; } else { var stateID = uWaze.model.cities.objects[street.attributes.cityID].attributes.stateID; if (typeof(stateID) === 'undefined') { result = false; } else { var stateName = uWaze.model.states.getObjectById(stateID).attributes.name; if (stateName === null) { stateName = ""; } var condTxt = tree.txt; if ((!getId("cbRSCaseSens").checked) && (tree.op != "4")) { condTxt = condTxt.toLowerCase(); stateName = stateName.toLowerCase(); } switch (tree.op) { case "0": result = stateName == condTxt; break; case "1": result = stateName != condTxt; break; case "2": result = stateName.indexOf(condTxt) >= 0; break; case "3": result = stateName.indexOf(condTxt) < 0; break; default: var re; if (getId("cbRSCaseSens").checked) { re = new RegExp(condTxt); } else { re = new RegExp(condTxt, "i"); } result = stateName.search(re) >= 0; break; } } } } if (tree.type === "State") { break; } case "AState": if (tree.type === "AState") { result = false; } var sid = segment.attributes.primaryStreetID; if (typeof(sid) === 'undefined' || sid === null) { result = false; } else { var street = uWaze.model.streets.getObjectById(sid); if (typeof(street) === 'undefined') { result = false; } else { var stateID = uWaze.model.cities.objects[street.attributes.cityID].attributes.stateID; if (typeof(street) === 'undefined') { result = false; } else { var stateName = uWaze.model.states.getObjectById(stateID).attributes.name; if (stateName === null) { stateName = ""; } for(i = 0; i < segment.attributes.streetIDs.length; i++){ var sid = segment.attributes.streetIDs[i]; if (sid !== null) { var street = uWaze.model.streets.getObjectById(sid); if (typeof(street) === 'undefined') { result = false; } else { var stateID = uWaze.model.cities.objects[street.attributes.cityID].attributes.stateID; if (typeof(stateID) === 'undefined') { result = false; } else { var stateName = uWaze.model.states.getObjectById(stateID).attributes.name; if (stateName === null) { stateName = ""; } var condTxt = tree.txt; if ((!getId("cbRSCaseSens").checked) && (tree.op != "4")) { condTxt = condTxt.toLowerCase(); stateName = cityName.toLowerCase(); } switch (tree.op) { case "0": result = result || (stateName == condTxt); break; case "1": result = result || (stateName != condTxt); break; case "2": result = result || (stateName.indexOf(condTxt) >= 0); break; case "3": result = result || (stateName.indexOf(condTxt) < 0); break; default: var re; if (getId("cbRSCaseSens").checked) { re = new RegExp(condTxt); } else { re = new RegExp(condTxt, "i"); } result = result || (stateName.search(re) >= 0); break; } } } } } } } } break; case "City": case "XCity": var sid = segment.attributes.primaryStreetID; if (typeof(sid) === 'undefined' || sid === null) { result = false; } else { var street = uWaze.model.streets.getObjectById(sid); if (typeof(street) === 'undefined') { result = false; } else { var cityName = uWaze.model.cities.objects[street.attributes.cityID].attributes.name; if (cityName === null) { cityName = ""; } var condTxt = tree.txt; if ((!getId("cbRSCaseSens").checked) && (tree.op != "4")) { condTxt = condTxt.toLowerCase(); cityName = cityName.toLowerCase(); } switch (tree.op) { case "0": result = cityName == condTxt; break; case "1": result = cityName != condTxt; break; case "2": result = cityName.indexOf(condTxt) >= 0; break; case "3": result = cityName.indexOf(condTxt) < 0; break; default: var re; if (getId("cbRSCaseSens").checked) { re = new RegExp(condTxt); } else { re = new RegExp(condTxt, "i"); } result = cityName.search(re) >= 0; break; } } } if (tree.type === "City") { break; } case "ACity": if (tree.type === "ACity") { result = false; } for(i = 0; i < segment.attributes.streetIDs.length; i++){ var sid = segment.attributes.streetIDs[i]; if (sid !== null) { var street = uWaze.model.streets.getObjectById(sid); if (typeof(street) === 'undefined') { result = false; } else { var cityName = uWaze.model.cities.objects[street.attributes.cityID].attributes.name; if (cityName === null) { cityName = ""; } var condTxt = tree.txt; if ((!getId("cbRSCaseSens").checked) && (tree.op != "4")) { condTxt = condTxt.toLowerCase(); cityName = cityName.toLowerCase(); } switch (tree.op) { case "0": result = result || (cityName == condTxt); break; case "1": result = result || (cityName != condTxt); break; case "2": result = result || (cityName.indexOf(condTxt) >= 0); break; case "3": result = result || (cityName.indexOf(condTxt) < 0); break; default: var re; if (getId("cbRSCaseSens").checked) { re = new RegExp(condTxt); } else { re = new RegExp(condTxt, "i"); } result = result || (cityName.search(re) >= 0); break; } } } } break; case "Street": case "XStreet": var sid = segment.attributes.primaryStreetID; if (typeof(sid) === 'undefined' || sid === null) { result = false; } else { var street = uWaze.model.streets.getObjectById(sid); if (typeof(street) === 'undefined') { result = false; } else { var streetName = street.attributes.name; if (streetName === null) { streetName = ""; } var condTxt = tree.txt; if ((!getId("cbRSCaseSens").checked) && (tree.op != "4")) { condTxt = condTxt.toLowerCase(); streetName = streetName.toLowerCase(); } switch (tree.op) { case "0": result = streetName == condTxt; break; case "1": result = streetName != condTxt; break; case "2": result = streetName.indexOf(condTxt) >= 0; break; case "3": result = streetName.indexOf(condTxt) < 0; break; default: var re; if (getId("cbRSCaseSens").checked) { re = new RegExp(condTxt); } else { re = new RegExp(condTxt, "i"); } result = streetName.search(re) >= 0; break; } } } if (tree.type === "Street") { break; } case "AStreet": if (tree.type === "AStreet") { result = false; } for(i = 0; i < segment.attributes.streetIDs.length; i++){ var sid = segment.attributes.streetIDs[i]; if (sid !== null) { var street = uWaze.model.streets.getObjectById(sid); if (typeof(street) === 'undefined') { result = false; } else { var streetName = street.attributes.name; if (streetName === null) { streetName = ""; } var condTxt = tree.txt; if ((!getId("cbRSCaseSens").checked) && (tree.op != "4")) { condTxt = condTxt.toLowerCase(); streetName = streetName.toLowerCase(); } switch (tree.op) { case "0": result = result || (streetName == condTxt); break; case "1": result = result || (streetName != condTxt); break; case "2": result = result || (streetName.indexOf(condTxt) >= 0); break; case "3": result = result || (streetName.indexOf(condTxt) < 0); break; default: var re; if (getId("cbRSCaseSens").checked) { re = new RegExp(condTxt); } else { re = new RegExp(condTxt, "i"); } result = result || (streetName.search(re) >= 0); break; } } } } break; case "NoName": if (tree.op) { result = typeof(segment.attributes.primaryStreetID) === 'undefined' || segment.attributes.primaryStreetID === null; } else { result = typeof(segment.attributes.primaryStreetID) !== 'undefined' && segment.attributes.primaryStreetID !== null; } break; case "ANoName": if (tree.op) { result = segment.attributes.streetIDs.length === 0; } else { result = segment.attributes.streetIDs.length > 0; } break; case "RoadType": if (tree.op === "0") { result = tree.id == segment.attributes.roadType; } else { result = tree.id != segment.attributes.roadType; } break; case "IsRound": if (tree.op) { result = segment.attributes.junctionID !== null; } else { result = segment.attributes.junctionID === null; } break; case "IsToll": if (tree.op) { result = segment.attributes.fwdToll || segment.attributes.revToll; } else { result = !(segment.attributes.fwdToll || segment.attributes.revToll); } break; case "Direction": var dir = 0; if (!segment.attributes.fwdDirection) { dir += 2; } if (!segment.attributes.revDirection) { dir += 1; } if (tree.op === "0") { result = tree.id == dir; } else { result = tree.id != dir; } break; case "Elevation": switch (tree.op) { case "0": result = parseInt(tree.id, 10) === segment.attributes.level; break; case "1": result = parseInt(tree.id, 10) !== segment.attributes.level; break; case "2": result = parseInt(tree.id, 10) < segment.attributes.level; break; case "3": result = parseInt(tree.id, 10) <= segment.attributes.level; break; case "4": result = parseInt(tree.id, 10) > segment.attributes.level; break; default: result = parseInt(tree.id, 10) >= segment.attributes.level; break; } break; case "Tunnel": if (tree.op) { result = (segment.attributes.flags & 1) !== 0; } else { result = (segment.attributes.flags & 1) === 0; } break; case "Unpaved": if (tree.op) { result = (segment.attributes.flags & 16) !== 0; } else { result = (segment.attributes.flags & 16) === 0; } break; case "HOV": if (tree.op) { result = (segment.attributes.flags & 128) !== 0; } else { result = (segment.attributes.flags & 128) === 0; } break; case "Headlights": if (tree.op) { result = (segment.attributes.flags & 32) !== 0; } else { result = (segment.attributes.flags & 32) === 0; } break; case "ManLock": if (segment.attributes.lockRank === null) { result = false; } else { switch (tree.op) { case "0": result = parseInt(tree.id, 10) === segment.attributes.lockRank + 1; break; case "1": result = parseInt(tree.id, 10) !== segment.attributes.lockRank + 1; break; case "2": result = parseInt(tree.id, 10) < segment.attributes.lockRank + 1; break; case "3": result = parseInt(tree.id, 10) <= segment.attributes.lockRank + 1; break; case "4": result = parseInt(tree.id, 10) > segment.attributes.lockRank + 1; break; default: result = parseInt(tree.id, 10) >= segment.attributes.lockRank + 1; break; } } break; case "TrLock": if (segment.attributes.lockRank === null) { switch (tree.op) { case "0": result = parseInt(tree.id, 10) === segment.attributes.rank + 1; break; case "1": result = parseInt(tree.id, 10) !== segment.attributes.rank + 1; break; case "2": result = parseInt(tree.id, 10) < segment.attributes.rank + 1; break; case "3": result = parseInt(tree.id, 10) <= segment.attributes.rank + 1; break; case "4": result = parseInt(tree.id, 10) > segment.attributes.rank + 1; break; default: result = parseInt(tree.id, 10) >= segment.attributes.rank + 1; break; } } else { result = false; } break; case "Speed": var spdDir = tree.op % 10; var spdCond = Math.floor(tree.op / 10); var fwdRes; var revRes; if (tree.txt === '') { fwdRes = typeof(segment.attributes.fwdMaxSpeed) !== 'undefined' && segment.attributes.fwdMaxSpeed !== null; revRes = typeof(segment.attributes.revMaxSpeed) !== 'undefined' && segment.attributes.revMaxSpeed !== null; } else { switch (spdCond) { case 0: // "=" if (speedInMiles) { fwdRes = parseInt(segment.attributes.fwdMaxSpeed, 10) === parseInt(tree.txt, 10) || parseInt(segment.attributes.fwdMaxSpeed, 10) === parseInt(tree.txt, 10) - 1; revRes = parseInt(segment.attributes.revMaxSpeed, 10) === parseInt(tree.txt, 10) || parseInt(segment.attributes.revMaxSpeed, 10) === parseInt(tree.txt, 10) - 1; } else { fwdRes = parseInt(segment.attributes.fwdMaxSpeed, 10) === parseInt(tree.txt, 10); revRes = parseInt(segment.attributes.revMaxSpeed, 10) === parseInt(tree.txt, 10); } break; case 1: // "!=" if (speedInMiles) { fwdRes = parseInt(segment.attributes.fwdMaxSpeed, 10) !== parseInt(tree.txt, 10) && parseInt(segment.attributes.fwdMaxSpeed, 10) !== parseInt(tree.txt, 10) - 1; revRes = parseInt(segment.attributes.revMaxSpeed, 10) !== parseInt(tree.txt, 10) && parseInt(segment.attributes.revMaxSpeed, 10) !== parseInt(tree.txt, 10) - 1; } else { fwdRes = parseInt(segment.attributes.fwdMaxSpeed, 10) !== parseInt(tree.txt, 10); revRes = parseInt(segment.attributes.revMaxSpeed, 10) !== parseInt(tree.txt, 10); } break; case 2: // ">" if (speedInMiles) { fwdRes = parseInt(segment.attributes.fwdMaxSpeed, 10) > parseInt(tree.txt, 10); revRes = parseInt(segment.attributes.revMaxSpeed, 10) > parseInt(tree.txt, 10); } else { fwdRes = parseInt(segment.attributes.fwdMaxSpeed, 10) > parseInt(tree.txt, 10); revRes = parseInt(segment.attributes.revMaxSpeed, 10) > parseInt(tree.txt, 10); } break; case 3: // ">=" if (speedInMiles) { fwdRes = parseInt(segment.attributes.fwdMaxSpeed, 10) >= parseInt(tree.txt, 10) - 1; revRes = parseInt(segment.attributes.revMaxSpeed, 10) >= parseInt(tree.txt, 10) - 1; } else { fwdRes = parseInt(segment.attributes.fwdMaxSpeed, 10) >= parseInt(tree.txt, 10); revRes = parseInt(segment.attributes.revMaxSpeed, 10) >= parseInt(tree.txt, 10); } break; case 4: // "<" if (speedInMiles) { fwdRes = parseInt(segment.attributes.fwdMaxSpeed, 10) < parseInt(tree.txt, 10) - 1; revRes = parseInt(segment.attributes.revMaxSpeed, 10) < parseInt(tree.txt, 10) - 1; } else { fwdRes = parseInt(segment.attributes.fwdMaxSpeed, 10) < parseInt(tree.txt, 10); revRes = parseInt(segment.attributes.revMaxSpeed, 10) < parseInt(tree.txt, 10); } break; default: // "<=" if (speedInMiles) { fwdRes = parseInt(segment.attributes.fwdMaxSpeed, 10) <= parseInt(tree.txt, 10); revRes = parseInt(segment.attributes.revMaxSpeed, 10) <= parseInt(tree.txt, 10); } else { fwdRes = parseInt(segment.attributes.fwdMaxSpeed, 10) <= parseInt(tree.txt, 10); revRes = parseInt(segment.attributes.revMaxSpeed, 10) <= parseInt(tree.txt, 10); } break; } } if (spdDir === 5) { fwdRes = fwdRes && !segment.attributes.fwdDirection; revRes = revRes && !segment.attributes.revDirection; } else { fwdRes = fwdRes && segment.attributes.fwdDirection; revRes = revRes && segment.attributes.revDirection; } switch (spdDir) { case 0: // "none" result = !fwdRes && !revRes; break; case 1: // "any" result = fwdRes || revRes; break; case 2: // "both" result = fwdRes && revRes; break; case 3: // "A->B" result = fwdRes; break; case 4: // "B->A" result = revRes; break; case 5: // "hidden" result = fwdRes || revRes; break; case 6: // "unverified" result = (fwdRes && segment.attributes.fwdMaxSpeedUnverified) || (revRes && segment.attributes.revMaxSpeedUnverified); break; default: // "only one" result = fwdRes !== revRes; break; } break; case "SpdC": switch (tree.op) { case "0": result = (!segment.attributes.fwdDirection || (segment.attributes.fwdFlags & 1) !== 1) && (!segment.attributes.revDirection || (segment.attributes.revFlags & 1) !== 1); break; case "1": result = (segment.attributes.fwdDirection && (segment.attributes.fwdFlags & 1) === 1) || (segment.attributes.revDirection && (segment.attributes.revFlags & 1) === 1); break; case "2": result = (segment.attributes.fwdDirection && (segment.attributes.fwdFlags & 1) === 1) && (segment.attributes.revDirection && (segment.attributes.revFlags & 1) === 1); break; case "3": result = segment.attributes.fwdDirection && (segment.attributes.fwdFlags & 1) === 1; break; case "4": result = segment.attributes.revDirection && (segment.attributes.revFlags & 1) === 1; break; case "5": result = (!segment.attributes.fwdDirection && (segment.attributes.fwdFlags & 1) === 1) || (!segment.attributes.revDirection && (segment.attributes.revFlags & 1) === 1); break; default: result = (segment.attributes.fwdDirection && (segment.attributes.fwdFlags & 1) === 1) != (segment.attributes.revDirection && (segment.attributes.revFlags & 1) === 1); break; } break; case "IsNew": if (tree.op) { result = segment.isNew(); } else { result = !segment.isNew(); } break; case "IsChngd": if (tree.op) { result = !segment.isUnchanged(); } else { result = segment.isUnchanged(); } break; case "OnScr": var eg = uWaze.map.getExtent().toGeometry(); var os = eg.intersects(segment.getOLGeometry()); if (tree.op) { result = os; } else { result = !os; } break; case "Restr": if (tree.op) { result = segment.getDrivingRestrictionCount() !== 0; } else { result = segment.getDrivingRestrictionCount() === 0; } break; case "HNs": if (tree.op) { result = segment.attributes.hasHNs; } else { result = !segment.attributes.hasHNs; } break; case "Restr2": var opDir = tree.op % 10; var x = Math.floor(tree.op / 10); var opLane = x % 10; var x = Math.floor(x / 10); var opCar = x % 10; var x = Math.floor(x / 10); var opType = x % 10; var x = Math.floor(x / 10); var opNum = x % 10; var x = Math.floor(x / 10); var opSel = x % 10; var x = Math.floor(x / 10); var opSubscr = x % 10; var x = Math.floor(x / 10); var opDays = x % 10; var x = Math.floor(x / 10); var opHours = x % 10; var x = Math.floor(x / 10); var opRange = x % 10; result = false; var restr = segment.attributes.restrictions; for(var i = 0; i < restr.length; i++) { var rtmp = true; switch(opDir) { case 1: if (restr[i]._direction !== 'BOTH') { rtmp = false; } break; case 2: if (restr[i]._direction !== 'FWD') { rtmp = false; } break; case 3: if (restr[i]._direction !== 'REV') { rtmp = false; } break; default: break; } if (opLane !== 0 && restr[i]._disposition !== opLane) { rtmp = false; } if (opCar === 9 && restr[i]._laneType !== null) { rtmp = false; } if (opCar !== 0 && opCar !== 9 && restr[i]._laneType !== opCar) { rtmp = false; } if (opDays !== 0 && restr[i]._timeFrames[0]._weekdays === 127) { rtmp = false; } if (opHours !== 0 && restr[i]._timeFrames[0]._fromTime === null) { rtmp = false; } if (opRange !== 0 && restr[i]._timeFrames[0]._startDate === null) { rtmp = false; } switch(opType) { case 1: if (restr[i]._defaultType !== 'BLOCKED' || !restr[i]._driveProfiles.has('FREE')) { rtmp = false; } else { if (opNum !== 0) { for (var j = 0; j < restr[i]._driveProfiles.get('FREE')._driveProfiles.length; j++) { if (restr[i]._driveProfiles.get('FREE')._driveProfiles[j]._numPassengers === opNum) { break; } } if (j === restr[i]._driveProfiles.get('FREE')._driveProfiles.length) { rtmp = false; } } switch (opSel) { case 1: // ANY for (var j = 0; j < tree.sel.length; j++) { for (var k = 0; k < restr[i]._driveProfiles.get('FREE')._driveProfiles.length; k++) { if (restr[i]._driveProfiles.get('FREE')._driveProfiles[k]._vehicleTypes[0] === RestrCarTypesN[tree.sel[j]]) { break; } } if (k < restr[i]._driveProfiles.get('FREE')._driveProfiles.length) { break; } } if (j === tree.sel.length) { rtmp = false; } break; case 2: // ALL for (var j = 0; j < tree.sel.length; j++) { for (var k = 0; k < restr[i]._driveProfiles.get('FREE')._driveProfiles.length; k++) { if (restr[i]._driveProfiles.get('FREE')._driveProfiles[k]._vehicleTypes[0] === RestrCarTypesN[tree.sel[j]]) { break; } } if (k === restr[i]._driveProfiles.get('FREE')._driveProfiles.length) { rtmp = false break; } } break; default: break; } if (opSubscr !== 0) { for (var j = 0; j < restr[i]._driveProfiles.get('FREE')._driveProfiles.length; j++) { if (restr[i]._driveProfiles.get('FREE')._driveProfiles[j]._subscriptions[0] === tree.subscr) { break; } } if (j === restr[i]._driveProfiles.get('FREE')._driveProfiles.length) { rtmp = false; } } } break; case 2: if (restr[i]._defaultType !== 'TOLL') { rtmp = false; } else { if (opNum !== 0) { for (var j = 0; j < restr[i]._driveProfiles.get('FREE')._driveProfiles.length; j++) { if (restr[i]._driveProfiles.get('FREE')._driveProfiles[j]._numPassengers === opNum) { break; } } if (j === restr[i]._driveProfiles.get('FREE')._driveProfiles.length) { rtmp = false; } } switch (opSel) { case 1: // ANY for (var j = 0; j < tree.sel.length; j++) { for (var k = 0; k < restr[i]._driveProfiles.get('FREE')._driveProfiles.length; k++) { if (restr[i]._driveProfiles.get('FREE')._driveProfiles[k]._vehicleTypes[0] === RestrCarTypesN[tree.sel[j]]) { break; } } if (k < restr[i]._driveProfiles.get('FREE')._driveProfiles.length) { break; } } if (j === tree.sel.length) { rtmp = false; } break; case 2: // ALL for (var j = 0; j < tree.sel.length; j++) { for (var k = 0; k < restr[i]._driveProfiles.get('FREE')._driveProfiles.length; k++) { if (restr[i]._driveProfiles.get('FREE')._driveProfiles[k]._vehicleTypes[0] === RestrCarTypesN[tree.sel[j]]) { break; } } if (k === restr[i]._driveProfiles.get('FREE')._driveProfiles.length) { rtmp = false break; } } break; default: break; } if (opSubscr !== 0) { for (var j = 0; j < restr[i]._driveProfiles.get('FREE')._driveProfiles.length; j++) { if (restr[i]._driveProfiles.get('FREE')._driveProfiles[j]._subscriptions[0] === tree.subscr) { break; } } if (j === restr[i]._driveProfiles.get('FREE')._driveProfiles.length) { rtmp = false; } } } break; case 3: if (restr[i]._defaultType !== 'BLOCKED' || restr[i]._driveProfiles.has('FREE')) { rtmp = false; } break; case 4: if (restr[i]._defaultType !== 'FREE') { rtmp = false; } else { switch (opSel) { case 1: // ANY for (var j = 0; j < tree.sel.length; j++) { for (var k = 0; k < restr[i]._driveProfiles.get('BLOCKED')._driveProfiles[0]._vehicleTypes.length; k++) { if (restr[i]._driveProfiles.get('BLOCKED')._driveProfiles[0]._vehicleTypes[k] === RestrCarTypesN[tree.sel[j]]) { break; } } if (k < restr[i]._driveProfiles.get('BLOCKED')._driveProfiles[0]._vehicleTypes.length) { break; } } if (j === tree.sel.length) { rtmp = false; } break; case 2: // ALL for (var j = 0; j < tree.sel.length; j++) { for (var k = 0; k < restr[i]._driveProfiles.get('BLOCKED')._driveProfiles[0]._vehicleTypes.length; k++) { if (restr[i]._driveProfiles.get('BLOCKED')._driveProfiles[0]._vehicleTypes[k] === RestrCarTypesN[tree.sel[j]]) { break; } } if (k === restr[i]._driveProfiles.get('BLOCKED')._driveProfiles[0]._vehicleTypes.length) { rtmp = false break; } } break; default: break; } } break; default: break; } if (rtmp) { result = true; break; } } break; case "Clsr": if (typeof(tree.op) === "boolean") { if (tree.op) { result = segment.hasClosures(); } else { result = !segment.hasClosures(); } } else { if (segment.hasClosures()) { result = false; for (var closure in uWaze.model.roadClosures.objects) { if (uWaze.model.roadClosures.objects[closure].segID === segment.attributes.id) { var cmpDateTxt; if (tree.op >= 6) { cmpDateTxt = uWaze.model.roadClosures.objects[closure].endDate; } else { cmpDateTxt = uWaze.model.roadClosures.objects[closure].startDate; } var cmpDateArr = cmpDateTxt.match(/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})/); var cmpDate = new Date(parseInt(cmpDateArr[1], 10), parseInt(cmpDateArr[2], 10) - 1, parseInt(cmpDateArr[3], 10), parseInt(cmpDateArr[4], 10), parseInt(cmpDateArr[5], 10), 0, 0); var cmpDays = Math.floor((cmpDate.getTime() - new Date().getTime()) / 86400000); switch (tree.op) { case 0: case 6: result = parseInt(tree.txt, 10) > cmpDays; break; case 1: case 7: result = parseInt(tree.txt, 10) <= cmpDays; break; case 2: case 8: result = parseInt(tree.txt, 10) < cmpDays; break; case 3: case 9: result = parseInt(tree.txt, 10) >= cmpDays; break; case 4: case 10: result = parseInt(tree.txt, 10) === cmpDays; break; case 5: case 11: result = parseInt(tree.txt, 10) !== cmpDays; break; default: result = false; break; } } } } else { result = false; } } break; case "ClReas": if (segment.hasClosures()) { for (var closure in uWaze.model.roadClosures.objects) { if (uWaze.model.roadClosures.objects[closure].attributes.segID === segment.attributes.id) { var condTxt = tree.txt; var reason = uWaze.model.roadClosures.objects[closure].attributes.reason; if ((!getId("cbRSCaseSens").checked) && (tree.op != "4")) { condTxt = condTxt.toLowerCase(); reason = reason.toLowerCase(); } switch (tree.op) { case "0": result = reason == condTxt; break; case "1": result = reason != condTxt; break; case "2": result = reason.indexOf(condTxt) >= 0; break; case "3": result = reason.indexOf(condTxt) < 0; break; default: var re; if (getId("cbRSCaseSens").checked) { re = new RegExp(condTxt); } else { re = new RegExp(condTxt, "i"); } result = reason.search(re) >= 0; break; } } } } else { result = false; } break; case "ClEvent": if (segment.hasClosures()) { for (var closure in uWaze.model.roadClosures.objects) { if (uWaze.model.roadClosures.objects[closure].attributes.segID === segment.attributes.id) { var condTxt = tree.txt; var eventId = uWaze.model.roadClosures.objects[closure].attributes.eventId; var eventNames; if (eventId == null) { eventNames = [{value: "None"}]; } else { eventNames = uWaze.model.majorTrafficEvents.objects[eventId].attributes.names; } for(i = 0; i < eventNames.length; i++){ var name = eventNames[i].value; if ((!getId("cbRSCaseSens").checked) && (tree.op != "4")) { condTxt = condTxt.toLowerCase(); reason = reason.toLowerCase(); } switch (tree.op) { case "0": result = result || name == condTxt; break; case "1": result = result || name != condTxt; break; case "2": result = result || name.indexOf(condTxt) >= 0; break; case "3": result = result || name.indexOf(condTxt) < 0; break; default: var re; if (getId("cbRSCaseSens").checked) { re = new RegExp(condTxt); } else { re = new RegExp(condTxt, "i"); } result = result || name.search(re) >= 0; break; } } } } } else { result = false; } break; case "ClWho": if (segment.hasClosures()) { for (var closure in uWaze.model.roadClosures.objects) { if (uWaze.model.roadClosures.objects[closure].attributes.segID === segment.attributes.id) { var condTxt = tree.txt; var userId; var opCmp = tree.op % 10; var opType = Math.floor(tree.op / 10); if (opType === 0) { userId = uWaze.model.roadClosures.objects[closure].attributes.createdBy; } else { userId = uWaze.model.roadClosures.objects[closure].attributes.updatedBy; } if (typeof(userId) === 'undefined' || userId === null) { name = ''; } else { name = uWaze.model.users.getObjectById(userId).attributes.userName; if ((typeof(name) === "undefined") || (name === null)) { return false; } } if ((!getId("cbRSCaseSens").checked) && (tree.op != 4)) { condTxt = condTxt.toLowerCase(); name = name.toLowerCase(); } switch (opCmp) { case 0: result = name == condTxt; break; case 1: result = name != condTxt; break; case 2: result = name.indexOf(condTxt) >= 0; break; case 3: result = name.indexOf(condTxt) < 0; break; default: var re; if (getId("cbRSCaseSens").checked) { re = new RegExp(condTxt); } else { re = new RegExp(condTxt, "i"); } result = name.search(re) >= 0; break; } } } } else { result = false; } break; case "Updtd": var name; if (typeof(segment.attributes.updatedBy) === 'undefined' || segment.attributes.updatedBy === null) { name = ''; } else { name = uWaze.model.users.getObjectById(segment.attributes.updatedBy).attributes.userName; if ((typeof(name) === "undefined") || (name === null)) { return false; } } var condTxt = tree.txt; if ((!getId("cbRSCaseSens").checked) && (tree.op != "4")) { condTxt = condTxt.toLowerCase(); name = name.toLowerCase(); } switch (tree.op) { case "0": result = name == condTxt; break; case "1": result = name != condTxt; break; case "2": result = name.indexOf(condTxt) >= 0; break; case "3": result = name.indexOf(condTxt) < 0; break; default: var re; if (getId("cbRSCaseSens").checked) { re = new RegExp(condTxt); } else { re = new RegExp(condTxt, "i"); } result = name.search(re) >= 0; break; } break; case "UpLev": var lev; if (typeof(segment.attributes.updatedBy) === 'undefined' || segment.attributes.updatedBy === null) { return false; } lev = uWaze.model.users.getObjectById(segment.attributes.updatedBy).attributes.rank; if (typeof(lev) !== "number") { return false; } lev += 1; switch (tree.op) { case "0": result = parseInt(tree.id, 10) === lev; break; case "1": result = parseInt(tree.id, 10) !== lev; break; case "2": result = parseInt(tree.id, 10) < lev; break; case "3": result = parseInt(tree.id, 10) <= lev; break; case "4": result = parseInt(tree.id, 10) > lev; break; default: result = parseInt(tree.id, 10) >= lev; break; } break; case "Crtd": var name; if (typeof(segment.attributes.createdBy) === 'undefined' || segment.attributes.createdBy === null) { name = ''; } else { name = uWaze.model.users.getObjectById(segment.attributes.createdBy).attributes.userName; if ((typeof(name) === "undefined") || (name === null)) { return false; } } var condTxt = tree.txt; if ((!getId("cbRSCaseSens").checked) && (tree.op != "4")) { condTxt = condTxt.toLowerCase(); name = name.toLowerCase(); } switch (tree.op) { case "0": result = name == condTxt; break; case "1": result = name != condTxt; break; case "2": result = name.indexOf(condTxt) >= 0; break; case "3": result = name.indexOf(condTxt) < 0; break; default: var re; if (getId("cbRSCaseSens").checked) { re = new RegExp(condTxt); } else { re = new RegExp(condTxt, "i"); } result = name.search(re) >= 0; break; } break; case "CrLev": var lev; if (typeof(segment.attributes.createdBy) === 'undefined' || segment.attributes.createdBy === null) { return false; } lev = uWaze.model.users.getObjectById(segment.attributes.createdBy).attributes.rank; if (typeof(lev) !== "number") { return false; } lev += 1; switch (tree.op) { case "0": result = parseInt(tree.id, 10) === lev; break; case "1": result = parseInt(tree.id, 10) !== lev; break; case "2": result = parseInt(tree.id, 10) < lev; break; case "3": result = parseInt(tree.id, 10) <= lev; break; case "4": result = parseInt(tree.id, 10) > lev; break; default: result = parseInt(tree.id, 10) >= lev; break; } break; case "LastU": var updatedDays; if (typeof(segment.attributes.updatedOn) === 'undefined' || sid === null) { updatedDays = 0; } else { updatedDays = Math.floor((new Date().getTime() - segment.attributes.updatedOn) / 86400000); } switch (tree.op) { case "0": result = parseInt(tree.txt, 10) === updatedDays; break; case "1": result = parseInt(tree.txt, 10) !== updatedDays; break; case "2": result = parseInt(tree.txt, 10) < updatedDays; break; case "3": result = parseInt(tree.txt, 10) <= updatedDays; break; case "4": result = parseInt(tree.txt, 10) > updatedDays; break; default: result = parseInt(tree.txt, 10) >= updatedDays; break; } break; case "Length": switch (tree.op) { case "0": result = parseInt(tree.txt, 10) === segment.attributes.length; break; case "1": result = parseInt(tree.txt, 10) !== segment.attributes.length; break; case "2": result = parseInt(tree.txt, 10) < segment.attributes.length; break; case "3": result = parseInt(tree.txt, 10) <= segment.attributes.length; break; case "4": result = parseInt(tree.txt, 10) > segment.attributes.length; break; default: result = parseInt(tree.txt, 10) >= segment.attributes.length; break; } break; case "RoutePrf": switch (tree.op) { case "0": if (typeof(segment.attributes.routingRoadType) !== 'number') { result = false; } else { result = (segment.attributes.roadType === 3 && segment.attributes.routingRoadType === 6) || (segment.attributes.roadType === 6 && segment.attributes.routingRoadType === 7) || (segment.attributes.roadType === 7 && segment.attributes.routingRoadType === 2) || (segment.attributes.roadType === 2 && segment.attributes.routingRoadType === 1); }; break; case "1": result = typeof(segment.attributes.routingRoadType) !== 'number'; break; default: if (typeof(segment.attributes.routingRoadType) !== 'number') { result = false; } else { result = (segment.attributes.roadType === 6 && segment.attributes.routingRoadType === 3) || (segment.attributes.roadType === 7 && segment.attributes.routingRoadType === 6) || (segment.attributes.roadType === 2 && segment.attributes.routingRoadType === 7) || (segment.attributes.roadType === 1 && segment.attributes.routingRoadType === 2); }; break; } break; case "RouteRoadType": var rrt; if (typeof(segment.attributes.routingRoadType) === 'number') { rrt = segment.attributes.routingRoadType; } else { rrt = segment.attributes.roadType; } if (tree.op === "0") { result = tree.id == rrt; } else { result = tree.id != rrt; } break; case "SegId": var ids = tree.txt.replace(/[^\d]/g,','); var idsArr = ids.split(','); switch (tree.op) { case "0": result = false; break; default: result = true; break; } for(i = 0; i < idsArr.length; i++){ if (idsArr[i] !== '') { switch (tree.op) { case "0": result = result || idsArr[i] == segment.attributes.id; break; default: result = result && idsArr[i] != segment.attributes.id; break; } } } break; case "PlaceId": var place = uWaze.model.venues.objects[tree.txt]; if (typeof(place) === 'undefined' || place.isPoint()) { result = false; } else { var polygon = place.getPolygonGeometry(); var points = segment.getOLGeometry().getSortedSegments(); switch (tree.op) { case "0": result = true; break; default: result = false; break; } for (i = 0; i < points.length; i++) { var p1 = new uOpenLayers.Geometry.Point(points[i].x1, points[i].y1); var p2 = new uOpenLayers.Geometry.Point(points[i].x2, points[i].y2); switch (tree.op) { case "0": result = result && polygon.containsPoint(p1) && polygon.containsPoint(p2); break; default: result = result || polygon.containsPoint(p1) || polygon.containsPoint(p2); break; } } } break; case "CommentId": var comment = uWaze.model.mapComments.objects[tree.txt]; if (typeof(comment) === 'undefined' || comment.isPoint()) { result = false; } else { var polygon = comment.getPolygonGeometry(); var points = segment.getOLGeometry().getSortedSegments(); switch (tree.op) { case "0": result = true; break; default: result = false; break; } for (i = 0; i < points.length; i++) { var p1 = new uOpenLayers.Geometry.Point(points[i].x1, points[i].y1); var p2 = new uOpenLayers.Geometry.Point(points[i].x2, points[i].y2); switch (tree.op) { case "0": result = result && polygon.containsPoint(p1) && polygon.containsPoint(p2); break; default: result = result || polygon.containsPoint(p1) || polygon.containsPoint(p2); break; } } } break; case "Edtbl": if (tree.op) { result = segment.arePropertiesEditable(); } else { result = !segment.arePropertiesEditable(); } break; case "Inbj": if (tree.op) { result = segment.isInBigJunction(); } else { result = !segment.isInBigJunction(); } break; case "UTurn": result = false; for(var seg2 in uWaze.model.turnGraph.adjacencyList.get(segment.attributes.id + 'f')) { seg2 = seg2.substring(0, seg2.length-1); if (seg2 == segment.attributes.id) { result = true; break; } if (!result) { for(var seg2 in uWaze.model.turnGraph.adjacencyList.get(segment.attributes.id + 'r')) { seg2 = seg2.substring(0, seg2.length-1); if (seg2 != segment.attributes.id) { result = true; break; } } } } if (!tree.op) { result = !result; } break; case "LWidth": var opDir = tree.op % 10; var opCond = Math.floor(tree.op / 10); var opValue = Math.round(tree.txt * 100); var fwdValue; if (segment.attributes.fromLanesInfo === null) { fwdValue = 0; } else { if (segment.attributes.fromLanesInfo.laneWidth === null) { fwdValue = -1; } else { fwdValue = segment.attributes.fromLanesInfo.laneWidth; } } var revValue; if (segment.attributes.toLanesInfo === null) { revValue = 0; } else { if (segment.attributes.toLanesInfo.laneWidth === null) { revValue = -1; } else { revValue = segment.attributes.toLanesInfo.laneWidth; } } var fwdRes; var revRes; switch (opCond) { case 0: // "=" if (speedInMiles) { fwdRes = fwdValue === opValue || fwdValue === opValue - 1; revRes = revValue === opValue || revValue === opValue - 1; } else { fwdRes = fwdValue === opValue; revRes = revValue === opValue; } break; case 1: // "!=" if (speedInMiles) { fwdRes = fwdValue !== opValue && fwdValue !== opValue - 1; revRes = revValue !== opValue && revValue !== opValue - 1; } else { fwdRes = fwdValue !== opValue; revRes = revValue !== opValue; } break; case 2: // ">" if (speedInMiles) { fwdRes = fwdValue > opValue; revRes = revValue > opValue; } else { fwdRes = fwdValue > opValue; revRes = revValue > opValue; } break; case 3: // ">=" if (speedInMiles) { fwdRes = fwdValue >= opValue - 1; revRes = revValue >= opValue - 1; } else { fwdRes = fwdValue >= opValue; revRes = revValue >= opValue; } break; case 4: // "<" if (speedInMiles) { fwdRes = fwdValue < opValue - 1; revRes = revValue < opValue - 1; } else { fwdRes = fwdValue < opValue; revRes = revValue < opValue; } break; case 5: // "<=" if (speedInMiles) { fwdRes = fwdValue <= opValue; revRes = revValue <= opValue; } else { fwdRes = fwdValue <= opValue; revRes = revValue <= opValue; } break; default: // "is default" fwdRes = fwdValue === -1; revRes = revValue === -1; } if (opDir === 5) { fwdRes = fwdRes && !segment.attributes.fwdDirection; revRes = revRes && !segment.attributes.revDirection; } else { fwdRes = fwdRes && segment.attributes.fwdDirection; revRes = revRes && segment.attributes.revDirection; } switch (opDir) { case 0: // "none" result = !fwdRes && !revRes; break; case 1: // "any" result = fwdRes || revRes; break; case 2: // "both" result = fwdRes && revRes; break; case 3: // "A->B" result = fwdRes; break; case 4: // "B->A" result = revRes; break; case 5: // "hidden" result = fwdRes || revRes; break; case 6: // "unverified" result = (fwdRes && segment.attributes.fwdMaxSpeedUnverified) || (revRes && segment.attributes.revMaxSpeedUnverified); break; default: // "only one" result = fwdRes !== revRes; break; } break; case "NrLanesW": var opDir = tree.op % 10; var opCond = Math.floor(tree.op / 10); var opValue = parseInt(tree.txt, 10); var fwdValue; if (segment.attributes.fromLanesInfo === null) { fwdValue = 0; } else { fwdValue = segment.attributes.fromLanesInfo.numberOfLanes; } var revValue; if (segment.attributes.toLanesInfo === null) { revValue = 0; } else { revValue = segment.attributes.toLanesInfo.numberOfLanes; } var fwdRes; var revRes; switch (opCond) { case 0: // "=" if (speedInMiles) { fwdRes = fwdValue === opValue || fwdValue === opValue - 1; revRes = revValue === opValue || revValue === opValue - 1; } else { fwdRes = fwdValue === opValue; revRes = revValue === opValue; } break; case 1: // "!=" if (speedInMiles) { fwdRes = fwdValue !== opValue && fwdValue !== opValue - 1; revRes = revValue !== opValue && revValue !== opValue - 1; } else { fwdRes = fwdValue !== opValue; revRes = revValue !== opValue; } break; case 2: // ">" if (speedInMiles) { fwdRes = fwdValue > opValue; revRes = revValue > opValue; } else { fwdRes = fwdValue > opValue; revRes = revValue > opValue; } break; case 3: // ">=" if (speedInMiles) { fwdRes = fwdValue >= opValue - 1; revRes = revValue >= opValue - 1; } else { fwdRes = fwdValue >= opValue; revRes = revValue >= opValue; } break; case 4: // "<" if (speedInMiles) { fwdRes = fwdValue < opValue - 1; revRes = revValue < opValue - 1; } else { fwdRes = fwdValue < opValue; revRes = revValue < opValue; } break; default: // "<=" if (speedInMiles) { fwdRes = fwdValue <= opValue; revRes = revValue <= opValue; } else { fwdRes = fwdValue <= opValue; revRes = revValue <= opValue; } break; } if (opDir === 5) { fwdRes = fwdRes && !segment.attributes.fwdDirection; revRes = revRes && !segment.attributes.revDirection; } else { fwdRes = fwdRes && segment.attributes.fwdDirection; revRes = revRes && segment.attributes.revDirection; } switch (opDir) { case 0: // "none" result = !fwdRes && !revRes; break; case 1: // "any" result = fwdRes || revRes; break; case 2: // "both" result = fwdRes && revRes; break; case 3: // "A->B" result = fwdRes; break; case 4: // "B->A" result = revRes; break; case 5: // "hidden" result = fwdRes || revRes; break; case 6: // "unverified" result = (fwdRes && segment.attributes.fwdMaxSpeedUnverified) || (revRes && segment.attributes.revMaxSpeedUnverified); break; default: // "only one" result = fwdRes !== revRes; break; } break; case "NrLanesG": var opDir = tree.op % 10; var opCond = Math.floor(tree.op / 10); var opValue = parseInt(tree.txt, 10); var fwdValue = segment.attributes.fwdLaneCount; var revValue = segment.attributes.revLaneCount;; var fwdRes; var revRes; switch (opCond) { case 0: // "=" if (speedInMiles) { fwdRes = fwdValue === opValue || fwdValue === opValue - 1; revRes = revValue === opValue || revValue === opValue - 1; } else { fwdRes = fwdValue === opValue; revRes = revValue === opValue; } break; case 1: // "!=" if (speedInMiles) { fwdRes = fwdValue !== opValue && fwdValue !== opValue - 1; revRes = revValue !== opValue && revValue !== opValue - 1; } else { fwdRes = fwdValue !== opValue; revRes = revValue !== opValue; } break; case 2: // ">" if (speedInMiles) { fwdRes = fwdValue > opValue; revRes = revValue > opValue; } else { fwdRes = fwdValue > opValue; revRes = revValue > opValue; } break; case 3: // ">=" if (speedInMiles) { fwdRes = fwdValue >= opValue - 1; revRes = revValue >= opValue - 1; } else { fwdRes = fwdValue >= opValue; revRes = revValue >= opValue; } break; case 4: // "<" if (speedInMiles) { fwdRes = fwdValue < opValue - 1; revRes = revValue < opValue - 1; } else { fwdRes = fwdValue < opValue; revRes = revValue < opValue; } break; default: // "<=" if (speedInMiles) { fwdRes = fwdValue <= opValue; revRes = revValue <= opValue; } else { fwdRes = fwdValue <= opValue; revRes = revValue <= opValue; } break; } if (opDir === 5) { fwdRes = fwdRes && !segment.attributes.fwdDirection; revRes = revRes && !segment.attributes.revDirection; } else { fwdRes = fwdRes && segment.attributes.fwdDirection; revRes = revRes && segment.attributes.revDirection; } switch (opDir) { case 0: // "none" result = !fwdRes && !revRes; break; case 1: // "any" result = fwdRes || revRes; break; case 2: // "both" result = fwdRes && revRes; break; case 3: // "A->B" result = fwdRes; break; case 4: // "B->A" result = revRes; break; case 5: // "hidden" result = fwdRes || revRes; break; case 6: // "unverified" result = (fwdRes && segment.attributes.fwdMaxSpeedUnverified) || (revRes && segment.attributes.revMaxSpeedUnverified); break; default: // "only one" result = fwdRes !== revRes; break; } break; case "Bool": if (tree.op === "0") { result = true; } else { result = false; } break; case "And": if (checkExpr (tree.L, segment)) { result = checkExpr (tree.R, segment); } else { result = false; } break; case "Or": if (checkExpr (tree.L, segment)) { result = true; } else { result = checkExpr (tree.R, segment); } break; case "Not": result = !checkExpr (tree.R, segment); break; case "Bkt": result = checkExpr (tree.L, segment); break; case "Connect": result = false; switch (tree.op) { case "0": if (segment.attributes.fromNodeID !== null) { var segIDs = uWaze.model.nodes.getObjectById(segment.attributes.fromNodeID).attributes.segIDs; for(var i = 0; i < segIDs.length; i++) { if (segIDs[i] !== segment.attributes.id) { var segment2 = uWaze.model.segments.getObjectById(segIDs[i]); if (typeof(segment2) !== 'undefined') { result = checkExpr (tree.L, segment2); if (result) { break; } } } } } if (!result) { if (segment.attributes.toNodeID !== null) { var segIDs = uWaze.model.nodes.getObjectById(segment.attributes.toNodeID).attributes.segIDs; for(var i = 0; i < segIDs.length; i++) { if (segIDs[i] !== segment.attributes.id) { var segment2 = uWaze.model.segments.getObjectById(segIDs[i]); if (typeof(segment2) !== 'undefined') { result = checkExpr (tree.L, segment2); if (result) { break; } } } } } } break; default: for(var seg2 in uWaze.model.turnGraph.adjacencyList.get(segment.attributes.id + 'f')) { seg2 = seg2.substring(0, seg2.length-1); if (seg2 != segment.attributes.id) { var segment2 = uWaze.model.segments.getObjectById(seg2); if (typeof(segment2) !== 'undefined') { result = checkExpr (tree.L, segment2); if (result) { break; } } } } if (!result) { for(var seg2 in uWaze.model.turnGraph.adjacencyList.get(segment.attributes.id + 'r')) { seg2 = seg2.substring(0, seg2.length-1); if (seg2 != segment.attributes.id) { var segment2 = uWaze.model.segments.getObjectById(seg2); if (typeof(segment2) !== 'undefined') { result = checkExpr (tree.L, segment2); if (result) { break; } } } } } break; } break; default: result = false; break; } return result; } function genExptrTxt(tree) { if (typeof (tree.type) === 'undefined') { return ""; } var result; switch (tree.type) { case "Country": result = 'Country ' + EqualOps[tree.op] + ' "' + Countries[tree.id] + '"'; break; case "State": case "City": case "Street": case "AState": case "XState": case "ACity": case "XCity": case "AStreet": case "XStreet": switch (tree.type) { case "AState": result = 'Alt. State '; break; case "XState": result = 'Prim. or Alt. State '; break; case "ACity": result = 'Alt. City '; break; case "XCity": result = 'Prim. or Alt. City '; break; case "AStreet": result = 'Alt. Street '; break; case "XStreet": result = 'Prim. or Alt. Street '; break; default: result = tree.type + ' '; break; } switch (tree.op) { case "0": case "1": case "4": result += StringOps[tree.op] + ' "' + tree.txt + '"'; break; default: result += StringOps[tree.op] + ' ("' + tree.txt + '")'; break; } break; case "NoName": if (tree.op) { result = 'Unnamed'; } else { result = 'Has name'; } break; case "ANoName": if (tree.op) { result = 'NO Alt. names'; } else { result = 'Has Alt. name(s)'; } break; case "RoadType": result = 'Road Type ' + EqualOps[tree.op] + ' "' + I18n.translations[I18n.currentLocale()].segment.road_types[tree.id] + '"'; break; case "IsToll": if (tree.op) { result = 'Is Toll Road'; } else { result = 'Is NOT Toll Road'; } break; case "IsRound": if (tree.op) { result = 'Is Roundabout'; } else { result = 'Is NOT Roundabout'; } break; case "Direction": result = 'Direction ' + EqualOps[tree.op] + ' "' + Directions[tree.id] + '"'; break; case "Elevation": if (tree.id == 0) { result = 'Elevation ' + IntegerOps[tree.op] + ' "Ground"'; } else { result = 'Elevation ' + IntegerOps[tree.op] + ' ' + tree.id; } break; case "Tunnel": if (tree.op) { result = 'Is Tunnel'; } else { result = 'Is NOT Tunnel'; } break; case "Unpaved": if (tree.op) { result = 'Is Unpaved'; } else { result = 'Is NOT Unpaved'; } break; case "HOV": if (tree.op) { result = 'Is next to carpool/HOV/bus lane'; } else { result = 'Is NOT next to carpool/HOV/bus lane'; } break; case "Headlights": if (tree.op) { result = 'Headlights are required'; } else { result = 'Headlights are NOT required'; } break; case "ManLock": result = 'Manual Locks ' + IntegerOps[tree.op] + ' ' + tree.id; break; case "TrLock": result = 'Traffic Locks ' + IntegerOps[tree.op] + ' ' + tree.id; break; case "Speed": if (typeof(tree.op) === "boolean") { if (tree.op) { tree.op = '1'; tree.txt = ''; } else { tree.op = '0'; tree.txt = ''; } } if (typeof(tree.op) === "string") { if (tree.op === '8') { tree.op = 1; } else { tree.op = parseInt(tree.op, 10); } } var spdDir = tree.op % 10; var spdCond = Math.floor(tree.op / 10); if (spdDir === 0) { result = 'Has NO speed limit'; } else if (spdDir !== 6) { result = 'Has speed limit'; } else { result = 'Has unverified speed limit'; } if (tree.txt !== '') { result += ' ' + IntegerOps[spdCond] + ' '; if (speedInMiles) { result += km2miles(parseInt(tree.txt, 10)) + ' mph'; } else { result += tree.txt + ' km/h'; } } if (spdDir !== 6) { if (spdDir === 0) { if (tree.txt !== '') { result += ' in any direction'; } } else { result += ' in ' + DirOps[spdDir] + ' direction'; if (spdDir === 2) { result += 's'; } } } break; case "SpdC": if (tree.op === '0') { result = 'Has NO avg. speed cam'; } else { result = 'Has avg. speed cam'; } if (tree.op === '0') { if (tree.txt !== '') { result += ' in any direction'; } } else { result += ' in ' + DirOps[tree.op] + ' direction'; if (tree.op === '2') { result += 's'; } } break; case "IsNew": if (tree.op) { result = 'Is New'; } else { result = 'Is NOT New'; } break; case "IsChngd": if (tree.op) { result = 'Is Changed'; } else { result = 'Is NOT Changed'; } break; case "OnScr": if (tree.op) { result = 'On Screen'; } else { result = 'OUT of Screen'; } break; case "Restr": if (tree.op) { result = 'Has restriction'; } else { result = 'Has NO restriction'; } break; case "HNs": if (tree.op) { result = 'Has house numbers'; } else { result = 'Has NO house numbers'; } break; case "Restr2": var opDir = tree.op % 10; var x = Math.floor(tree.op / 10); var opLane = x % 10; var x = Math.floor(x / 10); var opCar = x % 10; var x = Math.floor(x / 10); var opType = x % 10; var x = Math.floor(x / 10); var opNum = x % 10; var x = Math.floor(x / 10); var opSel = x % 10; var x = Math.floor(x / 10); var opSubscr = x % 10; var x = Math.floor(x / 10); var opDays = x % 10; var x = Math.floor(x / 10); var opHours = x % 10; var x = Math.floor(x / 10); var opRange = x % 10; result = 'Restriction'; if (opDir !== 0) { result += ' in ' + RestrDirs[opDir] + ' dir.'; } if (opLane !== 0) { if (opLane === 1) { result += ' ' + RestrLanes[opLane] + ' seg.'; } else { result += ' ' + RestrLanes[opLane] + ' lane'; } } if (opCar !== 0) { result += ' ' + RestrCars[opCar]; } if (opType !== 0) { result += ' driving is ' + RestrTypes[opType]; } if (opNum !== 0) { result += ' min. ' + opNum + ' passengers'; } if (opSel !== 0) { result += ' ' + RestrSelOps[opSel] + '('; for (var i = 0; i < tree.sel.length; i++) { if (i > 0) { result += ','; } result += '"' + I18n.translations[I18n.currentLocale()].restrictions.vehicle_types[RestrCarTypes[tree.sel[i]]] + '"'; } result += ')'; } if (opSubscr !== 0) { result += ' ' + Subscriptions[tree.subscr]; } if (opDays !== 0) { result += ' Days'; } if (opHours !== 0) { result += ' Hours'; } if (opRange !== 0) { result += ' Date Range'; } break; case "Clsr": if (typeof(tree.op) === "boolean") { if (tree.op) { result = 'Has closure'; } else { result = 'Has NO closure'; } } else { switch (tree.op) { case 0: result = "Closure starts before"; break; case 1: result = "Closure doesn't start before"; break; case 2: result = "Closure starts after"; break; case 3: result = "Closure doesn't start after"; break; case 4: result = "Closure starts in"; break; case 5: result = "Closure doesn't start in"; break; case 6: result = "Closure ends before"; break; case 7: result = "Closure doesn't end before"; break; case 8: result = "Closure ends after"; break; case 9: result = "Closure doesn't end after"; break; case 10: result = "Closure ends in"; break; case 11: result = "Closure doesn't end in"; break; default: result = "Error"; break; } result += ' ' + tree.txt + ' day'; if (tree.txt !== '1') { result += 's'; } } break; case "ClReas": result = 'Closure reason '; switch (tree.op) { case "0": case "1": case "4": result += StringOps[tree.op] + ' "' + tree.txt + '"'; break; default: result += StringOps[tree.op] + ' ("' + tree.txt + '")'; break; } break; case "ClEvent": result = 'Closure event '; switch (tree.op) { case "0": case "1": case "4": result += StringOps[tree.op] + ' "' + tree.txt + '"'; break; default: result += StringOps[tree.op] + ' ("' + tree.txt + '")'; break; } break; case "ClWho": var opCmp = tree.op % 10; var opType = Math.floor(tree.op / 10); result = 'Closure '; if (opType === 0) { result += 'created by '; } else { result += 'updated by '; } switch (opCmp) { case 0: case 1: case 4: result += StringOps[String(opCmp)] + ' "' + tree.txt + '"'; break; default: result += StringOps[String(opCmp)] + ' ("' + tree.txt + '")'; break; } break; case "Updtd": result = 'Updated by '; switch (tree.op) { case "0": case "1": case "4": result += StringOps[tree.op] + ' "' + tree.txt + '"'; break; default: result += StringOps[tree.op] + ' ("' + tree.txt + '")'; break; } break; case "UpLev": result = 'Updated by level ' + IntegerOps[tree.op] + ' ' + tree.id; break; case "Crtd": result = 'Created by '; switch (tree.op) { case "0": case "1": case "4": result += StringOps[tree.op] + ' "' + tree.txt + '"'; break; default: result += StringOps[tree.op] + ' ("' + tree.txt + '")'; break; } break; case "CrLev": result = 'Created by level ' + IntegerOps[tree.op] + ' ' + tree.id; break; case "LastU": result = 'Last update ' + IntegerOps[tree.op] + ' ' + tree.txt + ' days ago'; break; case "Length": result = 'Length ' + IntegerOps[tree.op] + ' '; if (speedInMiles) { if (tree.txt >= 1609) { result += decimalRound(tree.txt/1609.344, -2) + ' miles'; } else { result += Math.round(tree.txt/0.3048) + ' feet'; } } else { if (tree.txt >= 1000) { result += decimalRound(tree.txt/1000.0, -2) + ' km'; } else { result += tree.txt + ' m'; } } break; case "RoutePrf": result = 'Routing preference '; switch (tree.op) { case "0": result += 'Unfavored'; break; case "1": result += 'Neutral'; break; default: result += 'Preferred'; break; } break; case "RouteRoadType": result = 'Routing type ' + EqualOps[tree.op] + ' "' + I18n.translations[I18n.currentLocale()].segment.road_types[tree.id] + '"'; break; case "SegId": result = 'ID ' + StringOps[tree.op] + ' "' + tree.txt + '"'; break; case "PlaceId": switch (tree.op) { case "0": result = 'fully'; break; default: result = 'partially'; break; } result += ' inside Place ID "' + tree.txt + '"'; break; case "CommentId": switch (tree.op) { case "0": result = 'fully'; break; default: result = 'partially'; break; } result += ' inside Comment ID "' + tree.txt + '"'; break; case "Edtbl": if (tree.op) { result = 'Is Editable'; } else { result = 'Is NOT Editable'; } break; case "Inbj": if (tree.op) { result = 'Is in Junction Box'; } else { result = 'Is NOT in Junction Box'; } break; case "UTurn": if (tree.op) { result = 'Has U-Turn'; } else { result = 'Has NO U-Turns'; } break; case "LWidth": result = 'Lane width in '; tree.op = parseInt(tree.op, 10); var opDir = tree.op % 10; var opCond = Math.floor(tree.op / 10); result += DirOps[opDir] + ' direction'; if (opDir === 2) { result += 's'; } if (opCond == 9) { result += ' is default'; } else { result += ' ' + IntegerOps[opCond] + ' '; if (speedInMiles) { result += Math.round(tree.txt*100/0.3048)/100.0 + ' feet'; } else { result += Math.round(tree.txt*100)/100.0 + ' m'; } } break; case "NrLanesW": result = 'Nr. of lanes for width in '; tree.op = parseInt(tree.op, 10); var opDir = tree.op % 10; var opCond = Math.floor(tree.op / 10); result += DirOps[opDir] + ' direction'; if (opDir === 2) { result += 's'; } result += ' ' + IntegerOps[opCond] + ' ' + tree.txt; break; case "NrLanesG": result = 'Nr. of lanes for guidance in '; tree.op = parseInt(tree.op, 10); var opDir = tree.op % 10; var opCond = Math.floor(tree.op / 10); result += DirOps[opDir] + ' direction'; if (opDir === 2) { result += 's'; } result += ' ' + IntegerOps[opCond] + ' ' + tree.txt; break; case "Bool": if (tree.op === "0") { result = 'True'; } else { result = 'False'; } break; case "And": result = genExptrTxt(tree.L) + ' AND '; if (typeof (tree.R) !== 'undefined') { result += genExptrTxt(tree.R); } break; case "Or": result = genExptrTxt(tree.L) + ' OR '; if (typeof (tree.R) !== 'undefined') { result += genExptrTxt(tree.R); } break; case "Not": result = '! '; if (typeof (tree.R) !== 'undefined') { result += genExptrTxt(tree.R); } break; case "Bkt": result = '(' + genExptrTxt(tree.L) + ')'; break; case "Connect": switch (tree.op) { case "0": result = 'Connected to ('; break; default: result = 'Allowed to ('; break; } result += genExptrTxt(tree.L) + ')'; break; default: result = ""; break; } return result; } function displayExpr() { var ExprTxt = ""; for (var i = 0; i < BktCount; i ++) { ExprTxt += genExptrTxt(BktTrees[i]); switch (BktOps[i].type) { case "Connect": switch (BktOps[i].op) { case "0": ExprTxt += 'Connected to ('; break; default: ExprTxt += 'Allowed to ('; break; } break; default: ExprTxt += "("; break; } } ExprTxt += genExptrTxt(ExprTree); getId("outRSExpr").value = ExprTxt; } function displayStatus() { if (ExprStatus === 0 || ExprStatus === 2) { getId("btnRSAnd").disabled = true; getId("btnRSOr").disabled = true; if (ExprStatus === 2) { getId("btnRSNot").disabled = true; } else { getId("btnRSNot").disabled = false; } getId("btnRSRBkt").disabled = true; getId("btnRSSelect").disabled = true; } else { getId("btnRSAnd").disabled = false; getId("btnRSOr").disabled = false; getId("btnRSNot").disabled = true; if (BktCount === 0) { getId("btnRSRBkt").disabled = true; getId("btnRSSelect").disabled = false; } else { getId("btnRSRBkt").disabled = false; getId("btnRSSelect").disabled = true; } } getId("outRSNumBkt").value = BktCount; displayExpr(); } function addCondition(cond) { if (ExprStatus === 1) { makeAnd(); } if (typeof (ExprTree.type) === 'undefined') { ExprTree = cond; } else { if (typeof (ExprTree.R) === 'undefined') { ExprTree.R = cond; } else { ExprTree.R.R = cond; } } ExprStatus = 1; displayStatus (); } function makeCountry(ev) { var cond = {}; cond.type = "Country"; cond.op = getId("opRSCountry").value; cond.id = getId("selRSCountry").value; addCondition(cond); } function makeState(ev) { var cond = {}; cond.type = "State"; switch (getId("selRSAltState").value) { case "0": cond.type = "State"; break; case "1": cond.type = "AState"; break; default: cond.type = "XState"; break; } cond.op = getId("opRSState").value; cond.txt = getId("inRSState").value; addCondition(cond); } function makeCity(ev) { var cond = {}; switch (getId("selRSAltCity").value) { case "0": cond.type = "City"; break; case "1": cond.type = "ACity"; break; default: cond.type = "XCity"; break; } cond.op = getId("opRSCity").value; cond.txt = getId("inRSCity").value; addCondition(cond); } function makeStreet(ev) { var cond = {}; switch (getId("selRSAlttStreet").value) { case "0": cond.type = "Street"; break; case "1": cond.type = "AStreet"; break; default: cond.type = "XStreet"; break; } cond.op = getId("opRSStreet").value; cond.txt = getId("inRSStreet").value; addCondition(cond); } function makeNoName(ev) { var cond = {}; if (getId("cbRSAltNoName").checked) { cond.type = "ANoName"; } else { cond.type = "NoName"; } cond.op = getId("cbRSNoName").checked; addCondition(cond); } function makeRoadType(ev) { var cond = {}; cond.type = "RoadType"; cond.op = getId("opRSRoadType").value; cond.id = getId("selRSRoadType").value; addCondition(cond); } function makeIsRound(ev) { var cond = {}; cond.type = "IsRound"; cond.op = getId("cbRSIsRound").checked; addCondition(cond); } function makeIsToll(ev) { var cond = {}; cond.type = "IsToll"; cond.op = getId("cbRSIsToll").checked; addCondition(cond); } function makeDirection(ev) { var cond = {}; cond.type = "Direction"; cond.op = getId("opRSDirection").value; cond.id = getId("selRSDirection").value; addCondition(cond); } function makeElevation(ev) { var cond = {}; cond.type = "Elevation"; cond.op = getId("opRSElevation").value; cond.id = getId("selRSElevation").value; addCondition(cond); } function makeTunnel(ev) { var cond = {}; cond.type = "Tunnel"; cond.op = getId("cbRSTunnel").checked; addCondition(cond); } function makeUnpaved(ev) { var cond = {}; cond.type = "Unpaved"; cond.op = getId("cbRSUnpaved").checked; addCondition(cond); } function makeHOV(ev) { var cond = {}; cond.type = "HOV"; cond.op = getId("cbRSHOV").checked; addCondition(cond); } function makeHeadlights(ev) { var cond = {}; cond.type = "Headlights"; cond.op = getId("cbRSHeadlights").checked; addCondition(cond); } function makeManLock(ev) { var cond = {}; cond.type = "ManLock"; cond.op = getId("opRSManLock").value; cond.id = getId("selRSManLock").value; addCondition(cond); } function makeTrLock(ev) { var cond = {}; cond.type = "TrLock"; cond.op = getId("opRSTrLock").value; cond.id = getId("selRSTrLock").value; addCondition(cond); } function makeSpeed(ev) { var cond = {}; cond.type = "Speed"; cond.op = parseInt(getId("opRSSpeed").value, 10) + 10 * parseInt(getId("opRSSpeedComp").value, 10); var val = getId("inRSSpeed").value; if (isNaN(val) || val === '') { cond.txt = ''; } else { val = parseInt(val, 10); if (speedInMiles) { val = miles2km(val); } cond.txt = val; } addCondition(cond); } function makeSpdC(ev) { var cond = {}; cond.type = "SpdC"; cond.op = getId("opRSSpdC").value; addCondition(cond); } function makeIsNew(ev) { var cond = {}; cond.type = "IsNew"; cond.op = getId("cbRSIsNew").checked; addCondition(cond); } function makeIsChngd(ev) { var cond = {}; cond.type = "IsChngd"; cond.op = getId("cbRSIsChngd").checked; addCondition(cond); } function makeOnScr(ev) { var cond = {}; cond.type = "OnScr"; cond.op = getId("cbRSOnScr").checked; addCondition(cond); } function makeRestr(ev) { var cond = {}; cond.type = "Restr"; cond.op = getId("cbRSRestr").checked; addCondition(cond); } function makeHNs(ev) { var cond = {}; cond.type = "HNs"; cond.op = getId("cbRSHNs").checked; addCondition(cond); } function makeRestr2(ev) { var cond = {}; cond.type = "Restr2"; var opType = parseInt(getId("opRSResType").value, 10) cond.op = parseInt(getId("opRSResDir").value, 10) + parseInt(getId("opRSResLane").value, 10) * 10 + parseInt(getId("opRSResCar").value, 10) * 100 + opType * 1000; if ((opType === 1 || opType === 2)) { cond.op += parseInt(getId("opRSNumPass").value, 10) * 10000; if (hasSubcriptions) { if (getId("opRSRestrSubscr").value !== '-') { cond.op += 1000000; cond.subscr = getId("opRSRestrSubscr").value; } } } if (opType === 1 || opType === 2 || opType === 4) { cond.op += parseInt(getId("opRSRestrOp").value, 10) * 100000; var selectedValues = []; $("#opRSCarType :selected").each(function(){ selectedValues.push(parseInt($(this).val(), 10)); }); cond.sel = selectedValues; } if (getId("cbRSRestrDays").checked) { cond.op += 10000000; } if (getId("cbRSRestrHours").checked) { cond.op += 100000000; } if (getId("cbRSRestrRange").checked) { cond.op += 1000000000; } addCondition(cond); } function makeClsr(ev) { var cond = {}; cond.type = "Clsr"; if (parseInt(getId("opRSClsrStrtEnd").value, 10) === 0) { cond.op = getId("cbRSClsr").checked; } else { cond.op = (parseInt(getId("opRSClsrStrtEnd").value, 10) - 1) * 6 + parseInt(getId("opRSClsrBeforeAter").value, 10) * 2 + (getId("cbRSClsr").checked?0:1); } cond.txt = getId("inRSClsrDays").value; addCondition(cond); } function makeClReas(ev) { var cond = {}; cond.type = "ClReas"; cond.op = getId("opRSClReas").value; cond.txt = getId("inRSClReas").value; addCondition(cond); } function makeClEvent(ev) { var cond = {}; cond.type = "ClEvent"; cond.op = getId("opRSClEvent").value; cond.txt = getId("inRSClEvent").value; addCondition(cond); } function makeClWho(ev) { var cond = {}; cond.type = "ClWho"; cond.op = parseInt(getId("opRSClWho").value, 10) + 10 * parseInt(getId("opRSClWhoType").value, 10); cond.txt = getId("inRSClWho").value; addCondition(cond); } function makeUpdtd(ev) { var cond = {}; cond.type = "Updtd"; cond.op = getId("opRSUpdtd").value; cond.txt = getId("inRSUpdtd").value; addCondition(cond); } function makeUpLev(ev) { var cond = {}; cond.type = "UpLev"; cond.op = getId("opRSUpLev").value; cond.id = getId("selRSUpLev").value; addCondition(cond); } function makeCrtd(ev) { var cond = {}; cond.type = "Crtd"; cond.op = getId("opRSCrtd").value; cond.txt = getId("inRSCrtd").value; addCondition(cond); } function makeCrLev(ev) { var cond = {}; cond.type = "CrLev"; cond.op = getId("opRSCrLev").value; cond.id = getId("selRSCrLev").value; addCondition(cond); } function makeLastU(ev) { var cond = {}; cond.type = "LastU"; cond.op = getId("opRSLastU").value; cond.txt = getId("inRSLastU").value; if (isNaN(parseInt(cond.txt, 10))) { cond.txt = '1'; } addCondition(cond); } function makeLength(ev) { var cond = {}; cond.type = "Length"; cond.op = getId("opRSLength").value; var val = parseFloat(getId("inRSLength").value); if (isNaN(val)) { cond.txt = 0; } else { if (speedInMiles) { if (getId("unitRSLength").value === '0') { val *= 0.3048; } else { val *= 1609.344; } } else if (getId("unitRSLength").value === '1') { val *= 1000; } cond.txt = Math.round(val); } addCondition(cond); } function makeRoutePrf(ev) { var cond = {}; cond.type = "RoutePrf"; cond.op = getId("opRSRoutePrf").value; addCondition(cond); } function makeRouteRoadType(ev) { var cond = {}; cond.type = "RouteRoadType"; cond.op = getId("opRSRouteRoadType").value; cond.id = getId("selRSRouteRoadType").value; addCondition(cond); } function makeSegId(ev) { var cond = {}; cond.type = "SegId"; cond.op = getId("opRSSegId").value; cond.txt = getId("inRSSegId").value; addCondition(cond); } function makePlaceId(ev) { var cond = {}; cond.type = "PlaceId"; cond.op = getId("opRSPlaceId").value; cond.txt = getId("inRSPlaceId").value; addCondition(cond); } function makeCommentId(ev) { var cond = {}; cond.type = "CommentId"; cond.op = getId("opRSCommentId").value; cond.txt = getId("inRSCommentId").value; addCondition(cond); } function makeEdtbl(ev) { var cond = {}; cond.type = "Edtbl"; cond.op = getId("cbRSEdtbl").checked; addCondition(cond); } function makeInbj(ev) { var cond = {}; cond.type = "Inbj"; cond.op = getId("cbRSInbj").checked; addCondition(cond); } function makeUTurn(ev) { var cond = {}; cond.type = "UTurn"; cond.op = getId("cbRSUTurn").checked; addCondition(cond); } function makeLWidth(ev) { var cond = {}; cond.type = "LWidth"; cond.op = parseInt(getId("opRSLWidth").value, 10) + 10 * parseInt(getId("opRSLWidthComp").value, 10); var val = parseFloat(getId("inRSLWidth").value); if (isNaN(val)) { cond.txt = 0; } else { if (speedInMiles) { val *= 0.3048; } cond.txt = val; } addCondition(cond); } function makeNrLanesW(ev) { var cond = {}; cond.type = "NrLanesW"; cond.op = parseInt(getId("opRSNrLanesW").value, 10) + 10 * parseInt(getId("opRSNrLanesWComp").value, 10); var val = parseFloat(getId("inRSNrLanesW").value); if (isNaN(val)) { cond.txt = 0; } else { cond.txt = Math.round(val); } addCondition(cond); } function makeNrLanesG(ev) { var cond = {}; cond.type = "NrLanesG"; cond.op = parseInt(getId("opRSNrLanesG").value, 10) + 10 * parseInt(getId("opRSNrLanesGComp").value, 10); var val = parseFloat(getId("inRSNrLanesG").value); if (isNaN(val)) { cond.txt = 0; } else { cond.txt = Math.round(val); } addCondition(cond); } function makeBool(ev) { var cond = {}; cond.type = "Bool"; cond.op = getId("opRSBool").value; addCondition(cond); } function makeAnd(ev) { var op = {}; op.type = "And"; if (ExprTree.type === "Or") { if (typeof (ExprTree.R) !== 'undefined') { op.L = ExprTree.R; } ExprTree.R = op; } else { op.L = ExprTree; ExprTree = op; } ExprStatus = 0; displayStatus (); } function makeOr(ev) { var op = {}; op.type = "Or"; op.L = ExprTree; ExprTree = op; ExprStatus = 0; displayStatus (); } function makeNot(ev) { var op = {}; op.type = "Not"; if (typeof (ExprTree.type) === 'undefined') { ExprTree = op; } else { if (typeof (ExprTree.R) === 'undefined') { ExprTree.R = op; } else { ExprTree.R.R = op; } } ExprStatus = 2; displayStatus (); } function makeLBkt(ev) { if (ExprStatus === 1) { makeAnd(); } BktTrees[BktCount] = ExprTree; var cond = {}; cond.type = "Bkt"; BktOps[BktCount] = cond; ExprTree = new Object; BktCount ++; ExprStatus = 0; displayStatus (); } function makeConnect(ev) { if (ExprStatus === 1) { makeAnd(); } BktTrees[BktCount] = ExprTree; var cond = {}; cond.type = "Connect"; cond.op = getId("opRSConnect").value; BktOps[BktCount] = cond; ExprTree = new Object; BktCount ++; ExprStatus = 0; displayStatus (); } function makeRBkt(ev) { BktCount --; var cond = BktOps[BktCount]; cond.L = ExprTree; ExprTree = BktTrees[BktCount]; ExprStatus = 0; addCondition(cond); } function selectRoads() { getId("btnRSSelect").disabled = true; setTimeout(selectRoads2, 100); } function selectRoads2() { var foundSegs = []; var selected = 0; var max_sel_txt = getId("inRSLimit").value; var max_sel = parseInt(max_sel_txt, 10); var eg = uWaze.map.getExtent().toGeometry(); for (var seg in uWaze.model.segments.objects) { var segment = uWaze.model.segments.getObjectById(seg); if ((segment.arePropertiesEditable() || !getId("cbRSEditable").checked) && (eg.intersects(segment.getOLGeometry()) || !getId("cbRSOnScreen").checked)) { if (checkExpr(ExprTree, segment)) { foundSegs.push(segment); selected++; if ((getId("cbRSLimit").checked) && (selected === max_sel)) { break; } } } } uWaze.selectionManager.setSelectedModels(foundSegs); getId("btnRSSelect").disabled = false; } function clearExpr(ev) { ExprStatus = 0; ExprTree = {}; BktCount = 0; displayStatus (); } function delLast(ev) { if (typeof (ExprTree.type) === 'undefined') { if (BktCount > 0) { BktCount--; ExprTree = BktTrees[BktCount]; if (ExprTree.type === "Not") { ExprStatus = 2; } else { ExprStatus = 0; } } } else { switch (ExprTree.type) { case "And": if (typeof (ExprTree.R) === 'undefined') { ExprTree = ExprTree.L; ExprStatus = 1; } else { if (ExprTree.R.type === "Bkt") { BktTrees[BktCount] = ExprTree; ExprTree = ExprTree.R.L; delete BktTrees[BktCount].R; BktCount ++; ExprStatus = 1; } else if (ExprTree.R.type === "Not") { if (typeof (ExprTree.R.R) === 'undefined') { delete ExprTree.R; ExprStatus = 0; } else { delete ExprTree.R.R; ExprStatus = 2; } } else { delete ExprTree.R; ExprStatus = 0; } } break; case "Or": if (typeof (ExprTree.R) === 'undefined') { ExprTree = ExprTree.L; ExprStatus = 1; } else { if (ExprTree.R.type === "Bkt") { BktTrees[BktCount] = ExprTree; ExprTree = ExprTree.R.L; delete BktTrees[BktCount].R; BktCount ++; ExprStatus = 1; } else if (ExprTree.R.type === "Not") { if (typeof (ExprTree.R.R) === 'undefined') { delete ExprTree.R; ExprStatus = 0; } else { delete ExprTree.R.R; ExprStatus = 2; } } else if (ExprTree.R.type === "And") { if (typeof (ExprTree.R.R) === 'undefined') { ExprTree.R = ExprTree.R.L; ExprStatus = 1; } else { delete ExprTree.R.R; ExprStatus = 0; } } else { delete ExprTree.R; ExprStatus = 0; } } break; case "Bkt": case "Connect": BktTrees[BktCount] = {}; ExprTree = ExprTree.L; BktCount ++; ExprStatus = 1; break; default: ExprTree = {}; ExprStatus = 0; break; } } displayStatus (); } var icon_delete ="iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3ggaDwcglEfa9wAAAftJREFUOMvNks1qFEEUhb+q7uqedNMdTJwJdjBRdBYG/4MEsgiGBAIuBBF8D8GXcO/LuHAjQkQJoglOFiN0YH4MKBomM3a6a6rcTOvEyQNYUHA5de5368CF/+Z0CABoU6m3qdRL7a/u19v49XEvgBiHdJ0okUo1AExRXLsw7HUAuipOpF9p4EjMcf+PDiDLooVXla67X1tdiWqrK5FwZKOFWmghF6TyGrUnj6PaveVIuu5+C686ARDIEPDRQ0x/IKp3bsfKD7dVOLtdfbAVm88NQZ4D+CPvZISOCNek6748f+tGBUAIgaxfZdhsgrF8+7ibGa23Ett/PQHoEJAwoE1l2VH+q9mb16etMWAtwnH4/mnvaFicbMyT7ZTeUxESBnQImCfbkWHYtkWBLQqs1litAdr/Np8ClA+HYbU7u762NMwyjLVYaxme5Exfubz01Y275aCJCCl4U9HcQe3Rw7nB23cCY+ilBz8sEF9aPAcglbJHzeZhURwvXsTkp36g8BLhyJlf73cQ1tpemmZG5xtW5xu9NM2EENZqDZYZiZ+cuY2pCO533TjrunG2J4LN0QC5K4LNUv8igvXxnjKCkDBlIHqBt55h1TOKD4A38uTPUXc9hH5K/kbAwMJPoBBjIAVEgA+4o+YyogX02O0DA0CLM5KIs5ZsBJmofwPkNtFJWyXQAQAAAABJRU5ErkJggg=="; function loadCss() { var cssEl = document.createElement("style"); cssEl.type = "text/css"; var css = ".divRSRow, .divRSRow0 { clear: both; line-height: 25px; height: 25px; padding: 0 5px; border: 1px solid #CCC; }"; css += ".divRSRow a, .divRSRow0 a { display: block; width: 95%; }"; css += ".divRSRow { border-top: none; }"; css += ".divRSName { float: left; text-align: left; padding-left: 0; width: 250px; font-weight: 600; }"; css += ".divRSDel { float: right; width: 20px; }"; css += "#RSconditions .table { margin: 0; padding: 0; font-size: 11px; font-weight: 600; }"; css += "#RSconditions .table-condensed>tbody>tr>td {padding: 2px 0;}"; css += "input[type=checkbox] { margin-top: -.2em; margin-right: .3em; padding: 0; vertical-align:middle; }"; css += "#RSselection, #roadselector-tabs-editor, #RSoperations, #RSconditions, #RSsavedHdr { margin: 8px 0; padding: 0; }"; css += "#RSconditions input[type=text], #RSconditions input[type=number], #RSselection input[type=text], #RSselection input[type=number] { margin: 0 2px; padding: 0; height: 20px; border: 1px solid #CCC; font-weight: 700; }"; css += "#RSconditions input[type=number], #RSselection input[type=number] { text-align: right; }"; css += "#RSconditions label, #RSselection label { margin-right: 6px; font-size: 11px; font-weight: 600; }"; css += "#RSselection>button { margin: 10px 2px 0; padding: 0 15px; }"; css += "#RSoperations button { margin: 0 2px; padding: 0 10px; height: 20px; }"; css += "#RSconditions button, #RSconditions select:not([multiple]) { padding: 0 8px; height: 20px; }"; css += "#RSconditions select { margin: 0 2px; padding: 0; }"; css += "#roadselector-tabs li { width: 50%; text-align: center; height: 30px; }"; css += "#roadselector-tabs a { height: 30px; }"; cssEl.innerHTML = css; document.body.appendChild(cssEl); } function genSavedHTML () { getId('RSsavedTable').innerHTML=""; for (var i = 0; i < SavedQueries.length; i++) { var savedRow = document.createElement('div'); if (i == 0) { savedRow.className="divRSRow0"; } else { savedRow.className="divRSRow"; } savedRow.id="RSsavedRow_"+i; var namediv = document.createElement('div'); namediv.className="divRSName"; var namea = document.createElement('a'); namea.innerHTML=SavedQueries[i].name; namea.href = "#"; namea.onclick = getFunctionWithArgs(selectRow, [i]); namediv.appendChild(namea); savedRow.appendChild(namediv); var deletediv = document.createElement('div'); deletediv.className="divRSDel"; var deletea = document.createElement('a'); deletea.innerHTML="<img title='Delete' src='data:image/png;base64," +icon_delete +"'>"; deletea.href = "#"; deletea.onclick = getFunctionWithArgs(deleteRow, [i]); deletediv.appendChild(deletea); savedRow.appendChild(deletediv); getId('RSsavedTable').appendChild(savedRow); } } var SavedQueries = []; function makeSave(ev) { var name = getId("inRSSaveName").value.substring(0,40); var query = { name: name, ExprStatus: ExprStatus, ExprTree: clone(ExprTree), BktTrees: clone(BktTrees), BktOps: clone(BktOps), BktCount: BktCount }; var done = false; for (var i = 0; i < SavedQueries.length; i++) { if (SavedQueries[i].name === name) { SavedQueries[i] = query; done = true; break; } if (SavedQueries[i].name > name) { SavedQueries.splice(i, 0, query); done = true; break; } } if (!done) { SavedQueries.push(query); } localStorage.WMERoadSelector = JSON.stringify(SavedQueries); genSavedHTML(); } function saveOptions(ev) { var options = {}; options.cbRSEditable = getId("cbRSEditable").checked; options.cbRSCaseSens = getId("cbRSCaseSens").checked; options.cbRSOnScreen = getId("cbRSOnScreen").checked; options.cbRSLimit = getId("cbRSLimit").checked; options.inRSLimit = getId("inRSLimit").value; localStorage.WMERoadSelectorOptions = JSON.stringify(options); } function selectRow(id) { ExprStatus = SavedQueries[id].ExprStatus; ExprTree = clone(SavedQueries[id].ExprTree); BktTrees = clone(SavedQueries[id].BktTrees); BktCount = SavedQueries[id].BktCount; if (typeof(SavedQueries[id].BktOps) !== "undefined") { BktOps = clone(SavedQueries[id].BktOps); } else { BktOps = {}; for (var i = 0; i < BktCount; i++) { var cond = {}; cond.type = "Bkt"; BktOps[i] = cond; } } getId("inRSSaveName").value = SavedQueries[id].name; displayStatus (); } function deleteRow(id) { SavedQueries.splice(id, 1); localStorage.WMERoadSelector = JSON.stringify(SavedQueries); genSavedHTML(); } function getElementsByClassName(classname, node) { if(!node) { node = document.getElementsByTagName("body")[0]; } var a = []; var re = new RegExp('\\b' + classname + '\\b'); var els = node.getElementsByTagName("*"); for (var i=0,j=els.length; i<j; i++) { if (re.test(els[i].className)) { a.push(els[i]); } } return a; } function getFunctionWithArgs(func, args) { return ( function () { var json_args = JSON.stringify(args); return function() { var args = JSON.parse(json_args); func.apply(this, args); }; } )(); } function getId(node) { return document.getElementById(node); } function clone(obj) { var copy; if (null == obj || "object" != typeof obj) return obj; if (obj instanceof Date) { copy = new Date(); copy.setTime(obj.getTime()); return copy; } if (obj instanceof Array) { copy = []; for (var i = 0, len = obj.length; i < len; i++) { copy[i] = clone(obj[i]); } return copy; } if (obj instanceof Object) { copy = {}; for (var attr in obj) { if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]); } return copy; } throw new Error("Unable to copy obj! Its type isn't supported."); } function roadSelector_init() { uWaze = unsafeWindow.W; uOpenLayers = unsafeWindow.OpenLayers; hasStates = uWaze.model.hasStates(); speedInMiles = uWaze.model.isImperial; getSubscriptions(); if (localStorage.WMERoadSelector) { SavedQueries = JSON.parse(localStorage.WMERoadSelector); } loadCss(); var addon = document.createElement('section'); var lang = unsafeWindow.I18n.locale; if (lang === 'cs' || lang === 'sk') { addon.innerHTML = '<b><u><a href="https://www.waze.com/forum/viewtopic.php?f=22&t=101365" target="_blank">WME Road Selector</a></u></b> v' + GM_info.script.version; } else { addon.innerHTML = '<b><u><a href="https://www.waze.com/forum/viewtopic.php?f=819&t=112497" target="_blank">WME Road Selector</a></u></b> v' + GM_info.script.version; } var section = document.createElement('section'); section.style.fontSize = "11px"; section.style.width = "95%"; section.id = "RSselection"; section.style.marginBottom = "15px"; section.innerHTML = '<font style="float:right;"></font><h3>Selection</h3>' + '<output id="outRSExpr" class="well well-sm"></output>' + '<label><input type="checkbox" id="cbRSEditable" checked>Editable only</label>' + '<label><input type="checkbox" id="cbRSCaseSens" checked>Case sensitive</label>' + '<label><input type="checkbox" id="cbRSOnScreen">On screen</label><br>' + '<label><input type="checkbox" id="cbRSLimit">Limit # of segs</label>' + '<input type="number" min="1" max="999" value="100" id="inRSLimit" style="width: 40px; display: inline-block"><br>' + '<button class="btn btn-success" id="btnRSSelect">Select roads</button>' + '<button class="btn btn-primary" id="btnRSClear">Clear</button>' + '<button class="btn btn-danger" id="btnRSDel">Delete last</button>' ; addon.appendChild(section); var tabs = document.createElement("ul"); addon.appendChild(tabs); tabs.id = "roadselector-tabs"; tabs.style.width = "92%"; tabs.className = "nav nav-tabs"; tabs.innerHTML = '<li class="active"><a href="#roadselector-tabs-editor" data-toggle="tab">Editor</a></li>'; tabs.innerHTML += '<li class=""><a href="#roadselector-tabs-saved" data-toggle="tab">Saved</a></li>'; var tabcont = document.createElement("div"); tabcont.className = "tab-content"; tabcont.id = "roadselector-tab-content"; tabcont.style.padding = "0"; tabcont.style.margin = "0"; addon.appendChild(tabcont); var tabpane = document.createElement("section"); tabpane.className = "tab-pane active"; tabpane.id = "roadselector-tabs-editor"; tabcont.appendChild(tabpane); section = document.createElement('section'); section.style.fontSize = "11px"; section.id = "RSoperations"; section.innerHTML = '<h3>Operations</h3>' + '<button class="btn btn-warning" id="btnRSAnd">AND</button>' + '<button class="btn btn-warning" id="btnRSOr">OR</button>' + '<button class="btn btn-pastrama" id="btnRSNot" style="padding: 0 20px;">!</button>' + '<button class="btn btn-primary" id="btnRSLBkt" style="padding-left: 20px;">(</button>' + '<output id="outRSNumBkt" style="padding: 0; height: 20px; display: inline-block;">0</output>' + '<button class="btn btn-primary" id="btnRSRBkt" style="padding-right: 20px">)</button>' ; tabpane.appendChild(section); section = document.createElement('section'); section.style.fontSize = "10px"; section.style.width = "92%"; section.id = "RSconditions"; var str = '<h3>Conditions</h3>' + '<table class="table table-condensed table-striped table-hover">' + '<tr><td><label for="selRSCountry">Country</label><select id="opRSCountry"></select>' + '<select id="selRSCountry"></select></td>' + '<td><button class="btn btn-default" id="btnRSAddCountry">+</button></td></tr>'; if (hasStates) { str += '<tr><td><label>State<select id="opRSState"></select></label>' + '<input type="text" id="inRSState" onclick="this.focus();this.select()" size="10">' + '<select id="selRSAltState"><option value="0">prim.</option><option value="1">alt.</option><option value="2">any</option></select></td>' + '<td><button class="btn btn-default" id="btnRSAddState">+</button></td></tr>'; } str += '<tr><td><label for="inRSCity">City</label><select id="opRSCity"></select>' + '<input type="text" id="inRSCity" onclick="this.focus();this.select()" size="10">' + '<select id="selRSAltCity"><option value="0">prim.</option><option value="1">alt.</option><option value="2">any</option></select></td>' + '<td><button class="btn btn-default" id="btnRSAddCity">+</button></td></tr>' + '<tr><td><label for="inRSStreet">Street</label><select id="opRSStreet"></select>' + '<input type="text" id="inRSStreet" onclick="this.focus();this.select()" size="9">' + '<select id="selRSAlttStreet"><option value="0">prim.</option><option value="1">alt.</option><option value="2">any</option></select></td>' + '<td><button class="btn btn-default" id="btnRSAddStreet">+</button></td></tr>' + '<tr><td><label><input type="checkbox" id="cbRSNoName" checked>Unnamed segment</label> <label><input type="checkbox" id="cbRSAltNoName">alt.</label></td>' + '<td><button class="btn btn-default" id="btnRSAddNoName">+</button></td></tr>' + '<tr><td><label for="selRSRoadType">Road type</label><select id="opRSRoadType"></select>' + '<select id="selRSRoadType" style="width:50%"></select></td>' + '<td><button class="btn btn-default" id="btnRSAddRoadType">+</button></td></tr>' + '<tr><td><label><input type="checkbox" id="cbRSIsRound" checked>Roundabout</label></td>' + '<td><button class="btn btn-default" id="btnRSAddIsRound">+</button></td></tr>' + '<tr><td><label><input type="checkbox" id="cbRSIsToll" checked>Toll Road</label></td>' + '<td><button class="btn btn-default" id="btnRSAddIsToll">+</button></td></tr>' + '<tr><td><label for="selRSDirection">Direction</label><select id="opRSDirection"></select>' + '<select id="selRSDirection"></select></td>' + '<td><button class="btn btn-default" id="btnRSAddDirection">+</button>' + '<tr><td><label for="selRSElevation">Elevation</label><select id="opRSElevation"></select>' + '<select id="selRSElevation"></select></td>' + '<td><button class="btn btn-default" id="btnRSAddElevation">+</button>' + '<tr><td><label><input type="checkbox" id="cbRSTunnel" checked>Tunnel</label></td>' + '<td><button class="btn btn-default" id="btnRSAddTunnel">+</button></td></tr>' + '<tr><td><label><input type="checkbox" id="cbRSUnpaved" checked>Unpaved</label></td>' + '<td><button class="btn btn-default" id="btnRSAddUnpaved">+</button></td></tr>' + '<tr><td><label><input type="checkbox" id="cbRSHOV" checked>Next to carpool/HOV/bus lane</label></td>' + '<td><button class="btn btn-default" id="btnRSAddHOV">+</button></td></tr>' + '<tr><td><label><input type="checkbox" id="cbRSHeadlights" checked>Headlights required</label></td>' + '<td><button class="btn btn-default" id="btnRSAddHeadlights">+</button></td></tr>' + '<tr><td><label for="selRSManLock">Manual Lock</label><select id="opRSManLock"></select>' + '<select id="selRSManLock"></select></td>' + '<td><button class="btn btn-default" id="btnRSAddManLock">+</button>' + '<tr><td><label for="selRSTrLock">Traffic Lock</label><select id="opRSTrLock"></select>' + '<select id="selRSTrLock"></select></td>' + '<td><button class="btn btn-default" id="btnRSAddTrLock">+</button></td></tr>' + '<tr><td><label for="inRSSpeed">Spd. limit in</label><select id="opRSSpeed"></select>direction<br>' + '<select id="opRSSpeedComp"></select>' + '<input type="text" id="inRSSpeed" onclick="this.focus();this.select()" size="6"> ' + (speedInMiles?'mph':'km/h') +'</td>' + '<td><button class="btn btn-default" id="btnRSAddSpeed">+</button></td></tr>' + '<tr><td><label for="opRSSpdC">Avg. speed cam</label><select id="opRSSpdC"></select>dir.' + '<td><button class="btn btn-default" id="btnRSAddSpdC">+</button></td></tr>' + '<tr><td><label><input type="checkbox" id="cbRSIsNew" checked>New</label></td>' + '<td><button class="btn btn-default" id="btnRSAddIsNew">+</button></td></tr>' + '<tr><td><label><input type="checkbox" id="cbRSIsChngd" checked>Changed</label></td>' + '<td><button class="btn btn-default" id="btnRSAddIsChngd">+</button></td></tr>' + '<tr><td><label><input type="checkbox" id="cbRSOnScr" checked>On Screen</label></td>' + '<td><button class="btn btn-default" id="btnRSAddOnScr">+</button></td></tr>' + '<tr><td><label><input type="checkbox" id="cbRSRestr" checked>Has restriction</label></td>' + '<td><button class="btn btn-default" id="btnRSAddRestr"">+</button></td></tr>' + '<tr><td><label><input type="checkbox" id="cbRSHNs" checked>Has house numbers</label></td>' + '<td><button class="btn btn-default" id="btnRSAddHNs"">+</button></td></tr>' + '<tr><td><label><input type="checkbox" id="cbRSClsr" checked>Has closure</label>' + '<select id="opRSClsrStrtEnd"><option value="0">---</option><option value="1">starts</option><option value="2">ends</option></select><br>' + '<select id="opRSClsrBeforeAter"><option value="0">before</option><option value="1">after</option><option value="2">in</option></select>' + '<input type="number" min="-365" max="365" value="1" id="inRSClsrDays" style="width:40px;">days</td>' + '<td><button class="btn btn-default" id="btnRSAddClsr"">+</button></td></tr>' + '<tr><td><label for="inRSClReas">Closure reason</label><select id="opRSClReas"></select>' + '<input type="text" id="inRSClReas" onclick="this.focus();this.select()" size="9"></td>' + '<td><button class="btn btn-default" id="btnRSAddClReas">+</button></td></tr>' + '<tr><td><label for="inRSClEvent">Closure event</label><select id="opRSClEvent"></select>' + '<input type="text" id="inRSClEvent" onclick="this.focus();this.select()" size="9"></td>' + '<td><button class="btn btn-default" id="btnRSAddClEvent">+</button></td></tr>' + '<tr><td><label for="inRSClWho">Closure</label><select id="opRSClWhoType"><option value="0">crtd by</option><option value="1">upd. by</option></select>' + '<select id="opRSClWho"></select>' + '<input type="text" id="inRSClWho" onclick="this.focus();this.select()" size="4"></td>' + '<td><button class="btn btn-default" id="btnRSAddClWho">+</button></td></tr>' + '<tr><td><label for="inRSUpdtd">Updated by</label><select id="opRSUpdtd"></select>' + '<input type="text" id="inRSUpdtd" onclick="this.focus();this.select()" size="8"></td>' + '<td><button class="btn btn-default" id="btnRSAddUpdtd">+</button></td></tr>' + '<tr><td><label for="inRSUpLev">Updated by level</label><select id="opRSUpLev"></select>' + '<select id="selRSUpLev"></select></td>' + '<td><button class="btn btn-default" id="btnRSAddUpLev">+</button></td></tr>' + '<tr><td><label for="inRSCrtd">Created by</label><select id="opRSCrtd"></select>' + '<input type="text" id="inRSCrtd" onclick="this.focus();this.select()" size="8"></td>' + '<td><button class="btn btn-default" id="btnRSAddCrtd">+</button></td></tr>' + '<tr><td><label for="inRSCrLev">Created by level</label><select id="opRSCrLev"></select>' + '<select id="selRSCrLev"></select></td>' + '<td><button class="btn btn-default" id="btnRSAddCrLev">+</button></td></tr>' + '<tr><td><label for="inRSLastU">Last update</label><select id="opRSLastU"></select>' + '<input type="number" min="0" max="365" value="1" id="inRSLastU" size="3" style="width:40px;">days ago</td>' + '<td><button class="btn btn-default" id="btnRSAddLastU">+</button></td></tr>' + '<tr><td><label for="inRSLength">Length</label><select id="opRSLength"></select>' + '<input type="text" id="inRSLength" onclick="this.focus();this.select()" size="10">' + '<select id="unitRSLength"><option value="0">' + (speedInMiles?'feet':'m') + '</option><option value="1">' + (speedInMiles?'miles':'km') + '</option></select></td>' + '<td><button class="btn btn-default" id="btnRSAddLength">+</button></td></tr>' + '<tr><td><label for="opRSRoutePrf">Routing preference</label><select id="opRSRoutePrf"><option value="0">Unfavored</option><option selected="true" value="1">Neutral</option><option value="2">Preferred</option></select></td>' + '<td><button class="btn btn-default" id="btnRSAddRoutePrf">+</button></td></tr>' + '<tr><td><label for="selRSRouteRoadType">Routing type</label><select id="opRSRouteRoadType"></select>' + '<select id="selRSRouteRoadType" style="width:45%"></select></td>' + '<td><button class="btn btn-default" id="btnRSAddRouteRoadType">+</button></td></tr>' + '<tr><td><select id="opRSConnect"><option value="0">Connected</option><option value="1">Allowed</option></select><label for="opRSConnect">to (…)</label></td>' + '<td><button class="btn btn-default" id="btnRSAddConnect">+</button></td></tr>' + '<tr><td><label><input type="checkbox" id="cbRSUTurn" checked>Has U-Turn</label></td>' + '<td><button class="btn btn-default" id="btnRSAddUTurn">+</button></td></tr>' + '<tr><td><label for="inRSSegId">ID</label><select id="opRSSegId"></select>' + '<input type="text" id="inRSSegId" onclick="this.focus();this.select()" style="width:80px;"></td>' + '<td><button class="btn btn-default" id="btnRSAddSegId">+</button></td></tr>' + '<tr><td><select id="opRSPlaceId"><option value="0">fully</option><option value="1">partially</option></select><label for="inRSPlaceId">inside Place ID</label>' + '<input type="text" id="inRSPlaceId" onclick="this.focus();this.select()" style="width:80px;"></td>' + '<td><button class="btn btn-default" id="btnRSAddPlaceId">+</button></td></tr>' + '<tr><td><select id="opRSCommentId"><option value="0">fully</option><option value="1">partially</option></select><label for="inRSCommentId">inside Comment ID</label>' + '<input type="text" id="inRSCommentId" onclick="this.focus();this.select()" style="width:70px;"></td>' + '<td><button class="btn btn-default" id="btnRSAddCommentId">+</button></td></tr>' + '<tr><td><select id="opRSBool"><option value="0">True</option><option value="1">False</option></select></td>' + '<td><button class="btn btn-default" id="btnRSAddBool">+</button></td></tr>' + '<tr><td><label><input type="checkbox" id="cbRSEdtbl" checked>Editable</label></td>' + '<td><button class="btn btn-default" id="btnRSAddEdtbl">+</button></td></tr>' + '<tr><td><label><input type="checkbox" id="cbRSInbj" checked>In Junction Box</label></td>' + '<td><button class="btn btn-default" id="btnRSAddInbj">+</button></td></tr>' + '<tr><td><label for="inRSLWidth">Lane width in </label><select id="opRSLWidth"></select>direction<br>' + '<select id="opRSLWidthComp"></select>' + '<input type="text" id="inRSLWidth" onclick="this.focus();this.select()" size="10">' + (speedInMiles?'feet':'m') + '<td><button class="btn btn-default" id="btnRSAddLWidth">+</button></td></tr>' + '<tr><td><label for="inRSNrLanesW">Nr. of lanes for width</label><br>in<select id="opRSNrLanesW"></select>direction <br>' + '<select id="opRSNrLanesWComp"></select>' + '<input type="text" id="inRSNrLanesW" onclick="this.focus();this.select()" size="10">' + '<td><button class="btn btn-default" id="btnRSAddNrLanesW">+</button></td></tr>' + '<tr><td><label for="inRSNrLanesG">Nr. of lanes for guidance</label><br>in<select id="opRSNrLanesG"></select>direction <br>' + '<select id="opRSNrLanesGComp"></select>' + '<input type="text" id="inRSNrLanesG" onclick="this.focus();this.select()" size="10">' + '<td><button class="btn btn-default" id="btnRSAddNrLanesG">+</button></td></tr>' + '<tr><td><label>Restriction</label><select id="opRSResDir"></select>' +'<select id="opRSResLane"></select>' +'<select id="opRSResCar"></select>' +'<select id="opRSResType"></select>' +'<select id="opRSRestrOp"></select>' +'<select multiple id="opRSCarType"></select>' +'<select id="opRSNumPass"><option value="0">---</option><option value="2">min. 2 passengers</option><option value="3">min. 3 passengers</option><option value="4">min. 4 passengers</option></select>'; if (hasSubcriptions) { str += '<select id="opRSRestrSubscr"></select>'; } str += '<label><input type="checkbox" id="cbRSRestrDays">Days</label>' +'<label><input type="checkbox" id="cbRSRestrHours">Hours</label>' +'<label><input type="checkbox" id="cbRSRestrRange">Date Range</label>'; str += '</td>' + '<td><button class="btn btn-default" id="btnRSAddRestr2"">+</button></td></tr>' + '</table>'; section.innerHTML = str; tabpane.appendChild(section); tabpane = document.createElement("section"); tabpane.className = "tab-pane"; tabpane.id = "roadselector-tabs-saved"; tabcont.appendChild(tabpane); section = document.createElement('p'); section.style.fontSize = "11px"; section.style.width = "92%"; section.id = "RSsavedHdr"; section.innerHTML = '<div class="input-group">' + '<input type="text" id="inRSSaveName" class="form-control" placeholder="Type name…" onclick="this.focus();this.select()">' + '<span class="input-group-btn"><button class="btn btn-info"id="btnRSSave">Save</button></span>' + '</div>'; tabpane.appendChild(section); section = document.createElement('p'); section.style.paddingTop = "8px"; section.style.fontSize = "12px"; section.id = "RSsaved"; var savedTable = "<div id='RSsavedTable'></div>"; section.innerHTML = savedTable; tabpane.appendChild(section); const { tabLabel, tabPane } = uWaze.userscripts.registerSidebarTab("roadselector"); tabLabel.innerHTML = '<img src="' + GM_info.script.icon + '" width="16" height="16" style="margin-top: -2px;">';; tabLabel.title = 'Road Selector'; tabLabel.id = "sidepanel-roadselector"; tabPane.appendChild(addon); genSavedHTML(); populateOptions("opRSCountry", EqualOps); //populateCountries("selRSCountry"); document.addEventListener("wme-map-data-loaded", populateCountries); if (hasStates) { populateOptions("opRSState", StringOps); } populateOptions("opRSCity", StringOps); populateOptions("opRSStreet", StringOps); populateOptions("opRSRoadType", EqualOps); populateRoadTypes("selRSRoadType"); populateOptions("opRSDirection", EqualOps); populateOptions("selRSDirection", Directions); populateOptions("opRSElevation", IntegerOps); populateElevations("selRSElevation"); populateOptions("opRSManLock", IntegerOps); populateLocks("selRSManLock"); populateOptions("opRSTrLock", IntegerOps); populateLocks("selRSTrLock"); populateDirOps("opRSSpeed", true); populateOptions("opRSSpeedComp", IntegerOps); populateDirOps("opRSSpdC", false); populateOptions("opRSClReas", StringOps); populateOptions("opRSClEvent", StringOps); populateOptions("opRSClWho", StringOps); populateOptions("opRSUpdtd", StringOps); populateOptions("opRSUpLev", IntegerOps); populateLocks("selRSUpLev"); populateOptions("opRSCrtd", StringOps); populateOptions("opRSCrLev", IntegerOps); populateLocks("selRSCrLev"); populateOptions("opRSLastU", IntegerOps); populateOptions("opRSSegId", EqualOps); populateOptions("opRSLength", IntegerOps); populateOptions("opRSRouteRoadType", EqualOps); populateRoadTypes("selRSRouteRoadType"); populateDirOps("opRSLWidth", false); populateOptions("opRSLWidthComp", IntegerOps); populateDirOps("opRSNrLanesW", false); populateOptions("opRSNrLanesWComp", IntegerOps); populateDirOps("opRSNrLanesG", false); populateOptions("opRSNrLanesGComp", IntegerOps); populateOptions("opRSResDir", RestrDirs); populateOptions("opRSResLane", RestrLanes); populateOrderedOptions("opRSResCar", RestrCars, RestrCarsOrder); populateOptions("opRSResType", RestrTypes); populateOptions("opRSRestrOp", RestrSelOps); populateLocalizedOptions("opRSCarType", RestrCarTypes, I18n.translations[I18n.currentLocale()].restrictions.vehicle_types); if (hasSubcriptions) { populateObjectOptions('opRSRestrSubscr', Subscriptions); } var selId = getId("opRSLWidthComp"); var usrOption = document.createElement('option'); var usrText = document.createTextNode("is default"); usrOption.setAttribute('value', 9); usrOption.appendChild(usrText); selId.appendChild(usrOption); displayStatus (); getId("btnRSAddCountry").onclick = makeCountry; if (hasStates) { getId("btnRSAddState").onclick = makeState; } getId("btnRSAddCity").onclick = makeCity; getId("btnRSAddStreet").onclick = makeStreet; getId("btnRSAddNoName").onclick = makeNoName; getId("btnRSAddRoadType").onclick = makeRoadType; getId("btnRSAddIsRound").onclick = makeIsRound; getId("btnRSAddIsToll").onclick = makeIsToll; getId("btnRSAddDirection").onclick = makeDirection; getId("btnRSAddElevation").onclick = makeElevation; getId("btnRSAddTunnel").onclick = makeTunnel; getId("btnRSAddUnpaved").onclick = makeUnpaved; getId("btnRSAddHOV").onclick = makeHOV; getId("btnRSAddHeadlights").onclick = makeHeadlights; getId("btnRSAddManLock").onclick = makeManLock; getId("btnRSAddTrLock").onclick = makeTrLock; getId("btnRSAddSpeed").onclick = makeSpeed; getId("btnRSAddSpdC").onclick = makeSpdC; getId("btnRSAddIsNew").onclick = makeIsNew; getId("btnRSAddIsChngd").onclick = makeIsChngd; getId("btnRSAddOnScr").onclick = makeOnScr; getId("btnRSAddRestr").onclick = makeRestr; getId("btnRSAddHNs").onclick = makeHNs; getId("btnRSAddClsr").onclick = makeClsr; getId("btnRSAddClReas").onclick = makeClReas; getId("btnRSAddClEvent").onclick = makeClEvent; getId("btnRSAddClWho").onclick = makeClWho; getId("btnRSAddUpdtd").onclick = makeUpdtd; getId("btnRSAddUpLev").onclick = makeUpLev; getId("btnRSAddCrtd").onclick = makeCrtd; getId("btnRSAddCrLev").onclick = makeCrLev; getId("btnRSAddLastU").onclick = makeLastU; getId("btnRSAddLength").onclick = makeLength; getId("btnRSAddRoutePrf").onclick = makeRoutePrf; getId("btnRSAddRouteRoadType").onclick = makeRouteRoadType; getId("btnRSAddConnect").onclick = makeConnect; getId("btnRSAddSegId").onclick = makeSegId; getId("btnRSAddPlaceId").onclick = makePlaceId; getId("btnRSAddCommentId").onclick = makeCommentId; getId("btnRSAddRestr2").onclick = makeRestr2; getId("btnRSAddEdtbl").onclick = makeEdtbl; getId("btnRSAddInbj").onclick = makeInbj; getId("btnRSAddUTurn").onclick = makeUTurn; getId("btnRSAddLWidth").onclick = makeLWidth; getId("btnRSAddNrLanesW").onclick = makeNrLanesW; getId("btnRSAddNrLanesG").onclick = makeNrLanesG; getId("btnRSAddBool").onclick = makeBool; getId("btnRSAnd").onclick = makeAnd; getId("btnRSOr").onclick = makeOr; getId("btnRSNot").onclick = makeNot; getId("btnRSLBkt").onclick = makeLBkt; getId("btnRSRBkt").onclick = makeRBkt; getId("btnRSSelect").onclick = selectRoads; getId("btnRSClear").onclick = clearExpr; getId("btnRSDel").onclick = delLast; getId("btnRSSave").onclick = makeSave; if (localStorage.WMERoadSelectorOptions) { var options = JSON.parse(localStorage.WMERoadSelectorOptions); getId("cbRSEditable").checked = options.cbRSEditable; getId("cbRSCaseSens").checked = options.cbRSCaseSens; getId("cbRSOnScreen").checked = options.cbRSOnScreen; getId("cbRSLimit").checked = options.cbRSLimit; getId("inRSLimit").value = options.inRSLimit; } saveOptions(); getId("cbRSEditable").onchange = saveOptions; getId("cbRSCaseSens").onchange = saveOptions; getId("cbRSOnScreen").onchange = saveOptions; getId("cbRSLimit").onchange = saveOptions; getId("inRSLimit").onchange = saveOptions; if (SavedQueries.length > 0) { $('#roadselector-tabs a[href="#roadselector-tabs-saved"]').tab('show'); } unsafeWindow.RoadSelector = { checkSegment: function(expression, segment) { if (typeof(expression) === 'undefined' || expression === null) { return false; } else { return checkExpr(expression, segment); } }, getCurrentExpression: function() { if (ExprStatus === 1 && BktCount === 0) { var e = clone(ExprTree); return e; } else { return null; } }, getSavedNames: function() { var lst = []; for (var i = 0; i < SavedQueries.length; i++) { if (SavedQueries[i].ExprStatus === 1) { lst.push(SavedQueries[i].name); } } return lst; }, getSavedExpression: function(name) { for (var i = 0; i < SavedQueries.length; i++) { if (SavedQueries[i].ExprStatus === 1 && SavedQueries[i].BktCount === 0 && SavedQueries[i].name === name) { var e = clone(SavedQueries[i].ExprTree); return e; } } return null; }, getExpressionText: function(expression) { if (typeof(expression) === 'undefined' || expression === null) { return 'Wrong expression!'; } else { return genExptrTxt(expression); } } }; } document.addEventListener("wme-ready", roadSelector_init, {once: true});