// ==UserScript== // @name WME Advanced Closures // @version 2022.07.26.01 // @description Recurrent and imported closures in the Waze Map Editor // @namespace WMEAC // @include https://www.waze.com/editor* // @include https://www.waze.com/*/editor* // @include https://beta.waze.com/editor* // @include https://beta.waze.com/*/editor* // @exclude https://www.waze.com/user/* // @exclude https://www.waze.com/*/user/* // @icon data:image/png;base64,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 // @grant unsafeWindow // @grant GM_xmlhttpRequest // @connect holidayapi.com // @copyright 2018, dummyd2, seb-d59, WazeDev // @author dummyd2, seb-d59, WazeDev // ==/UserScript== /******* * * You are free to: * Share, copy, and redistribute the script in any medium or format * under the following terms: * Attribution - You must give appropriate credit. You may do so in any * reasonable manner, but not in any way that suggests the licensor * endorses you or your use. * * NonCommercial - You may not use the script for commercial purposes. * * NoModifications - You may NOT MODIFY the script. * * You are invited to contact authors on waze forum for more details. * ********/ /* global $ */ /* global W */ /* global OpenLayers */ /* global require */ /* global _ */ /* global I18n */ /*jshint multistr: true */ /*********************************************** *** IN INCLUDED FILE : *** *** include/downloadHelper.js *** ***********************************************/ /**** DOWNLOAD HELPER **********************/ /******** AUTO INJECTED PART ***************/ function WMEAC_downloadHelperInjected() { window.WMEAC_downloadHelper = { jobs: [], _waitForData: function (id) { if (this.jobs.length<=id) { this.jobs[id].callback({url: null, data: null, callback: this.jobs[id].callback, status: "error", error: "Request not found"}); } else { if (this.jobs[id].status=="success" || this.jobs[id].status=="error") this.jobs[id].callback(this.jobs[id]); else { if (this.jobs[id].status=="downloading" && this.jobs[id].progressCallback) { this.jobs[id].progressCallback(this.jobs[id]); } var _this=this; window.setTimeout(function () { _this._waitForData(id); }, 500); } } }, add: function (url, callback, progressCallback) { this.jobs.push({url: url, data: null, callback: callback, progressCallback: progressCallback, status: "added", progression: 0, error: ""}); var _this=this; window.setTimeout(function () { _this._waitForData(_this.jobs.length-1); }, 500); } }; } var WMEAC_downloadHelperInjectedScript = document.createElement("script"); WMEAC_downloadHelperInjectedScript.textContent = '' + WMEAC_downloadHelperInjected.toString() + ' \n' + 'WMEAC_downloadHelperInjected();'; WMEAC_downloadHelperInjectedScript.setAttribute("type", "application/javascript"); document.body.appendChild(WMEAC_downloadHelperInjectedScript); /******** SANDBOX PART ***************/ function lookFordownloadHelperJob() { for (var i=0; i dt2.startDate ); }; WMEAC.solveOverlaps = function (closureToAdd, existingClosureList, mode) { // sort existing closures: var ecs = existingClosureList.map(function (e) { return { isNew: false, ref: e, startDate: e.startDate, endDate: e.endDate}; }); // append new closureToAdd.isNew=true; ecs.push(closureToAdd); var changes=true; while (changes) { changes=false; ecs.sort(function (a, b) { return (new Date(a.startDate) - new Date(b.startDate)); }); for (var i=1; i=range2.start && range1.end<=range2.end) { ecs.splice(indexOfNew, 1); } else if (range1.startrange2.end) { ecs.push({isNew: true, startDate: r2.endDate, endDate: r1.endDate}); r1.endDate=r2.startDate; } else if (range1.startrange2.end) { r1.startDate = r2.endDate; } break; case 3: // force: cut/split/delete existing and keep new range1.start=new Date(r1.startDate); range1.end=new Date(r1.endDate); range2.start=new Date(r2.startDate); range2.end=new Date(r2.endDate); changes=true; if (range1.start>range2.start && range1.end=range2.end) { ecs.splice(indexOfExisting, 1); } else if (range1.startrange2.end) { r2.endDate = r1.startDate; } break; } } } } return ecs; }; // tests: // WMEAC.solveOverlaps({startDate: '2016-01-10 00:00', endDate: '2016-01-20 00:00'}, // [ {startDate: '2016-01-05 00:00', endDate: '2016-01-15 00:00', reason: 'bla bla'}], 0); // WMEAC.solveOverlaps({startDate: '2016-01-10 00:00', endDate: '2016-01-20 00:00'}, // [ {startDate: '2016-01-15 00:00', endDate: '2016-01-25 00:00', reason: 'bla bla'}], 0); // WMEAC.solveOverlaps({startDate: '2016-01-10 00:00', endDate: '2016-01-20 00:00'}, // [ {startDate: '2016-01-05 00:00', endDate: '2016-01-25 00:00', reason: 'bla bla'}], 0); // WMEAC.solveOverlaps({startDate: '2016-01-10 00:00', endDate: '2016-01-20 00:00'}, // [ {startDate: '2016-01-12 00:00', endDate: '2016-01-18 00:00', reason: 'bla bla'}], 0); // WMEAC.solveOverlaps({startDate: '2016-01-10 00:00', endDate: '2016-01-20 00:00'}, // [ {startDate: '2016-01-10 00:00', endDate: '2016-01-20 00:00', reason: 'bla bla'}], 0); // WMEAC.solveOverlaps({startDate: '2016-01-10 00:00', endDate: '2016-01-20 00:00'}, // [ {startDate: '2016-01-05 00:00', endDate: '2016-01-10 00:00', reason: 'bla bla'}, // {startDate: '2016-01-20 00:00', endDate: '2016-01-25 00:00', reason: 'bla bla'}], 0); // WMEAC.solveOverlaps({startDate: '2016-01-10 00:00', endDate: '2016-01-20 00:00'}, // [ {startDate: '2016-01-05 00:00', endDate: '2016-01-15 00:00', reason: 'bla bla'}, // {startDate: '2016-01-16 00:00', endDate: '2016-01-25 00:00', reason: 'bla bla'}], 0); WMEAC.getCountriesFromSegmentSet = function (segs) { var cids = segs.map(function (s) { if (s.attributes.hasOwnProperty('primaryStreetID') && s.attributes.primaryStreetID!=null) { var stid = s.attributes.primaryStreetID; if (W.model.streets.objects.hasOwnProperty(stid)) { var st = W.model.streets.objects[stid]; if (st.hasOwnProperty('cityID') && st.cityID!=null && typeof st.cityID != 'undefined') { var ctid = st.cityID; if (W.model.cities.objects.hasOwnProperty(ctid)) return W.model.cities.objects[ctid].countryID; } } } return null; }).filter(function (cid) { return (cid!=null); }); return (W.model.countries.getObjectArray(function (c) { return cids.indexOf(c.id)!=-1; })); }; WMEAC.getOppositeClosure = function (closure) { return W.model.roadClosures.getObjectArray(function (c) { return (closure.reason == c.reason && closure.startDate == c.startDate && closure.endDate == c.endDate && closure.segID == c.segID && closure.forward != c.forward); }); }; WMEAC.getCityStreetsFromSegmentSet = function (segs) { var r={}; function add(city, street) { if (!r.hasOwnProperty(city)) r[city]={}; if (!r[city].hasOwnProperty(street)) r[city][street]=0; r[city][street]++; } segs.forEach(function (s) { var city='noCity'; if (s.attributes.primaryStreetID!=null && W.model.streets.objects.hasOwnProperty(s.attributes.primaryStreetID)) { var st = W.model.streets.objects[s.attributes.primaryStreetID]; if (st.hasOwnProperty('cityID') && st.cityID!=null && typeof st.cityID != 'undefined') { var ctid = st.cityID; if (W.model.cities.objects.hasOwnProperty(ctid)) { if (!W.model.cities.objects[ctid].isEmpty) city=W.model.cities.objects[ctid].name; } } if (W.model.streets.objects[s.attributes.primaryStreetID].isEmpty) add(city, 'noStreet'); else add(city, W.model.streets.objects[s.attributes.primaryStreetID].name); } }); return r; }; WMEAC.download = function (data, filename) { var element = document.createElement('a'); element.style.display = 'none'; element.setAttribute('href', encodeURI('data:text/plain,' + data)); element.setAttribute('download', filename); document.body.appendChild(element); element.click(); document.body.removeChild(element); }; WMEAC.buildPermalink = function (data) { var getvars = []; for (var m in data) { if (data.hasOwnProperty(m)) { getvars.push('' + m + '=' + data[m]); } } return document.location.protocol + '//' + document.location.host + document.location.pathname + '?' + getvars.join('&'); }; WMEAC.sharedClosureDirection = { A_TO_B: 1, B_TO_A: 2, TWO_WAY: 3 }; WMEAC.zoomToRoadType = function(e) { let allRoadTypes = [1,2,3,4,5,6,7,8,9,10,15,16,17,18,19,20,22]; if (e < 14) { return []; } switch (e) { case 14: return [2, 3, 4, 6, 7, 14]; case 15: return [2, 3, 4, 6, 7, 8, 9, 10, 14, 16,17, 18, 19, 20, 22]; case 16: case 17: case 18: case 19: case 20: case 21: case 22: default: return allRoadTypes; } } /*********************************************** *** END OF INCLUDED FILE : *** *** include/util.js *** ***********************************************/ /*********************************************** *** IN INCLUDED FILE : *** *** include/css.js *** ***********************************************/ var cssElt = WMEAC.createElement({type: "style"}); cssElt.type = "text/css"; var css=""; css += ".slashed:after { content: ''; position: relative; width: 140%; height: 1px; display: block; background: red; transform: rotate(-30deg); margin-top: -50%; margin-left: -20%; }"; css += ".wmeac-sidepanel button { border: none; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; border-top-left-radius: 5px; border-top-right-radius: 5px; background-color: #F1DDDB }"; css += "#wmeac-progressBarInfo { display: none; width: 90%; float: left; position: absolute; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; margin-bottom: -100%; background-color: #c9e1e9; z-index: 999; margin: 5px; margin-right: 20px; }"; css += ".wmeac-progressBarBG { margin-top: 2px; margin-bottom: 2px; margin-left: 2px; margin-right: 2px; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; padding-right: 0px; width: 33%; background-color: #93c4d3; border: 3px rgb(147, 196, 211); border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; height: 22px;}"; css += ".wmeac-progressBarFG { float: left; position: relative; bottom: 22px; height: 0px; text-align: center; width: 100% }"; css += ".wmeac-csv-button { border: none; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; border-top-left-radius: 5px; border-top-right-radius: 5px; background-color: #F1DDDB; display: inline-block; padding: 6px 12px; cursor: pointer; text-align: center; font-weight: bold; }"; css += ".wmeac-closuredialog { border: 2px solid #F1DDDB; width: 100%; float: left; display: none; position: absolute; padding: 0 0px; border-bottom-left-radius: 10px; border-bottom-right-radius: 10px; border-top-left-radius: 10px; border-top-right-radius: 10px; background-color: #FDEDEB; width: 500px; z-index: 9999; left: 80px; top: 10px;}"; css += ".wmeac-closuredialog button { border: none; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; border-top-left-radius: 5px; border-top-right-radius: 5px; background-color: #F1DDDB; margin: 3px; }"; css += ".wmeac-closuredialog h1 { background-color: #F1DDDB; text-align: center; font-size: medium; margin-top: 0px; padding: 10px;}"; css += ".wmeac-closuredialog .content { padding: 10px;}"; css += ".wmeac-closuredialog .content table { witdh: 100%; border: none; font-size: 10px; text-transform: uppercase;}"; css += ".wmeac-closuredialog .content table tbody tr { vertical-align: top;}"; css += ".wmeac-closuredialog .content table tbody tr td { padding-right: 2px; padding-left: 2px;}"; css += ".wmeac-closuredialog-fromgroup { display: inline-block; }"; css += ".wmeac-nav-tabs>ul { border-bottom: 1px solid #F6C3BE }"; css += ".wmeac-nav-tabs>li { float: left; margin-bottom: -1px; }"; css += ".wmeac-nav-tabs>li>a { border: 1px solid #F6C3BE; border-top-left-radius: 5px; border-top-right-radius: 5px; margin-right: 2px;}"; css += ".wmeac-nav-tabs>li.active>a { background-color: rgba(0, 0, 0, 0); border-bottom: 1px solid #FDEDEB}"; css += ".wmeac-nav-tabs>li:not(.active)>a { background-color: #DADBDC}"; //css += ".wmeac-nav-tabs>li:not(.active)>a:hover { background-color: #DADBDC}"; css += ".wmeac-tab-pane {border: 1px solid #F6C3BE; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; border-top-left-radius: 0px; border-top-right-radius: 0px; padding: 5px;}"; css += ".wmeac-closuredialog .footer { height: 40px; padding: 0 10px;}"; css += "#wmeac-csv-closures-list ul { list-style-type: none; padding: 0px;}"; css += "#wmeac-csv-closures-list ul li { width: 100%; height: 42px; border-radius: 4px; margin-top: 1px; }"; css += "#wmeac-csv-closures-list ul li > * { display: table-cell; vertical-align: middle;}"; css += ".wmeac-csv-closures-list-add { background-color: #C6DFFF; }"; css += ".wmeac-csv-closures-list-remove { background-color: #FFC65F; }"; css += ".wmeac-csv-closures-list-failed { background-color: #FF8585; }"; css += ".wmeac-csv-closures-list-done { background-color: #B9FAB1; }"; css += ".wmeac-csv-closures-list-col-action { width: 14px; min-width: 14px; }"; css += ".wmeac-csv-closures-list-col-lr { font-size: xx-small; width: 100%; }"; css += ".wmeac-csv-closures-list-col-lr > * { height: 14px; overflow-y: hidden; vertical-align: middle; }"; css += ".wmeac-csv-closures-list-col-dates { width: 75px; min-width: 75px; font-size: xx-small; text-align: center; }"; css += ".wmeac-csv-closures-list-col-dates > * { height: 14px; overflow-y: hidden; vertical-align: center; }"; css += ".wmeac-csv-closures-list-col-dir { width: 35px; min-width: 35px; text-align: center; }"; css += ".wmeac-csv-closures-list-col-it { width: 15px; min-width: 15px; }"; css += ".wmeac-csv-closures-list-col-target { width: 15px; min-width: 15px; }"; css += ".wmeac-csv-closures-list-col-apply { width: 15px; min-width: 15px; }"; css += ".wmeac-csv-closures-minilog { font-size: xx-small; font-family: monospace; border: 2px solid #F6C3BE; border-top: none; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: #FFFFFF; }"; css += "#wmeac-csv-closures-log { font-size: xx-small; font-family: monospace; border: 2px solid #F6C3BE; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; border-top-left-radius: 5px; border-top-right-radius: 5px; padding-top: 8px; position: relative; margin-top: 10px; }"; css += "#wmeac-csv-closures-log:before { content: \"Logs\"; position: absolute; top: -8px; left: 5px; float: left; background: #F6C3BE; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; border-top-left-radius: 5px; border-top-right-radius: 5px; padding: 2px; }"; css += "#wmeac-csv-closures-preview { font-size: small; white-space: nowrap; font-family: monospace; border: 2px solid #F6C3BE; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; border-top-left-radius: 5px; border-top-right-radius: 5px; padding-top: 8px; position: relative; min-height: 20px; }"; css += "#wmeac-csv-closures-preview:before { content: \"Preview\"; position: absolute; top: -8px; left: 5px; float: left; background: #F6C3BE; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; border-top-left-radius: 5px; border-top-right-radius: 5px; padding: 2px; }"; css += ".wmeac-hl:after { content: \"\\f018\"; position: relative; display: block; margin-top: -100%; margin-left: 50%; font-family: FontAwesome; }"; cssElt.innerHTML = css; document.body.appendChild(cssElt); /*********************************************** *** END OF INCLUDED FILE : *** *** include/css.js *** ***********************************************/ // boostrap and init (wait for waze UI and objects) /*********************************************** *** IN INCLUDED FILE : *** *** include/init.js *** ***********************************************/ WMEAC.bootstrapAC = function () { window.setTimeout(WMEAC.initialize, 500); }; WMEAC.initialize = function () { WMEAC.log ("init"); WMEAC.waitForWaze(function () { WMEAC.load(); WMEAC.log("presets", WMEAC.presets); WMEAC.initUI(); }); WMEAC.log ("init done"); }; WMEAC.waitForWaze = function(handler) { var APIRequired=[{o: "W"}, {o: "W.model"}, {o: "W.map"}, {o: "W.loginManager"}, {o: "W.app.layout.model"}, {o: "W.Config"}, {o: "W.controller"} ]; for (var i=0; i 0) WMEAC.installButtonInClosureTab(node); } else { for (var j=0; j0) node = clist[0]; } if (!node) return; // test if we already there if ($(node).find('#wmeac-closuretab-add-advanced-closure-button').length==0) { var addCL = WMEAC.getElementsByClassName('add-closure-button', node); var addACBtn = WMEAC.createElement({type: 'wz-button', id: 'wmeac-closuretab-add-advanced-closure-button', className: 'wmeac-button'}); addACBtn.innerHTML=' Add advanced closure'; addACBtn.addEventListener('click', WMEAC.showAddAdvancedClosure); if (addCL.length > 0) addCL[0].after(addACBtn); } }; WMEAC.showAddAdvancedClosure = function() { // init if needed and show modal dialog var ACDiv = WMEAC.getId('wmeac-add-advanced-closure-dialog'); if (ACDiv==null) { ACDiv = WMEAC.createElement({type: 'div', id: 'wmeac-add-advanced-closure-dialog', className: 'wmeac-closuredialog'}); ACDiv.innerHTML=WMEAC.HTMLTemplates.advancedClosureDialog; W.map.getOLMap().div.appendChild(ACDiv); window.setTimeout(WMEAC.connectAdvancedClosureDialogHandlers); ACDiv.style.display="none"; //W.selectionManager.events.register("selectionchanged", null, WMEAC.refreshClosureList); } if (ACDiv.style.display=="block") // already shown => reset position { $(ACDiv).css({left: '80px', top: '20px'}); } else { ACDiv.style.display="block"; W.selectionManager.events.register("selectionchanged", null, WMEAC.refreshClosureList); W.selectionManager.events.register("selectionchanged", null, WMEAC.refreshClosureListFromSelection); WMEAC.refreshClosureListFromSelection(); } //window.setTimeout(function () { $('#wmeac-add-advanced-closure-dialog').find('.input-group-addon').css({display:"table-cell"}); }); $(ACDiv).find('.input-group-addon').css({display:"table-cell"}); WMEAC.showClosuresLayer(true); }; WMEAC.HTMLTemplates={}; var rangeStartEndUI ='\
\ \
\
\ \ \ \ \
\
\
\
\ \
\
\ \ \ \ \
\
\
'; var startTimeAndDurationUI = '\
\ \
\
\ \ \ \ \
\
\
\
\ \
\
\ \ \ \ \ \ D\ \
\
\ \ \ \ \
\
\
\ '; var descriptionUI = '\
\ \
\ \
\
\ '; var locationUI = '\
\ \
\ \
\
\ '; var directionUI = '\
\ \
\ \
\
\ '; var ignoreTrafficUI = '\
\ \
\ '; var MTEUI = '\
\ \
\ \
\
\ '; var overlapModeUI = '\
\ \
\ \
\
\ '; var tabRepeatUI = '\
\
\
\ \ times\
\
\
\
\
\
\ \ every\ \ \ \ D\ \ H\ \ M\ \
\
\
\ '; if(!I18n.translations[I18n.locale].date.abbr_day_names){ I18n.translations[I18n.locale].date.abbr_day_names = []; _.forOwn(I18n.translations[I18n.locale].date, (v,k) => { if(k.indexOf("abbr_day_names_") > -1) { I18n.translations[I18n.locale].date.abbr_day_names.push(v)}}); } var daysOfWeekUI = _(I18n.translations[I18n.locale].date.abbr_day_names).clone(); daysOfWeekUI.push(daysOfWeekUI.shift()); var tabEachUI = '
\
\ \
\ ' + daysOfWeekUI.map(function (d, i) { return '
\ \
\ '; }).join('') + '
'; var tabHolidayUI = '\ \ '; var tabPresetsUI = '\
\
\
\ \
\
\ \ \ \ \ \ \ \
\
\ \
\
\ \ \ \ \
\
\
\
\
\ \
\
\ \ \ \ \
\
\
\
\
\ '; var tabsUI ='\ \
\
\ ' + tabRepeatUI + '\
\
\ ' + tabEachUI + '\
\
\ ' + tabHolidayUI + '\
\
\ ' + tabPresetsUI + '\
\
'; var footerUI = '\ '; WMEAC.HTMLTemplates.advancedClosureDialog='\

Advanced closures

\
\ \ \ \ \ \
' + rangeStartEndUI + startTimeAndDurationUI + '\ ' + descriptionUI + directionUI + ignoreTrafficUI + MTEUI +// overlapModeUI + '\
' + tabsUI + '
' + footerUI; WMEAC.connectAdvancedClosureDialogHandlers = function () { var e = null; e=WMEAC.getId('wmeac-advanced-closure-dialog-exportCSV-button'); if (e) { e.addEventListener('click', function() { var rc = WMEAC.buildClosuresListFromRecurringUI(); if (rc.error!="") { alert("Can't apply closures.\nPlease, check all parameters."); return; } if (W.selectionManager.getSelectedFeatures().length==0 || W.selectionManager.getSelectedFeatures()[0].model.type!="segment") { alert("Please, select segment(s) before."); return; } var reason = $('#wmeac-advanced-closure-dialog-reason').val(); //var cllocation = $('#wmeac-advanced-closure-dialog-location').val(); var direction = $('#wmeac-advanced-closure-dialog-direction').val(); var isIT = $('#wmeac-advanced-closure-dialog-ignoretraffic').is(':checked'); var mteId = $("#wmeac-advanced-closure-dialog-mteid").val(); var mte = W.model.majorTrafficEvents.getObjectById(mteId); closureList = rc.list.map(function (e) { //return {reason: reason, direction: direction, startDate: e.start, endDate: e.end, location: cllocation, permanent: isIT}; var details = {reason: reason, direction: direction, startDate: e.start, endDate: e.end, location: "", permanent: isIT}; if (mte) details.eventId = mte.id; return details; }); // save selection list var selection = _.map(W.selectionManager.getSelectedFeatures(), 'model'); var selectionReversed=[]; if (direction!='3') // not two way { var rev = W.selectionManager.getReversedSegments(); selection=selection.filter(function (e) { if (rev[e.attributes.id]) { selectionReversed.push(e); return false; } return true; }); } var lonlat=W.map.getCenter().transform(W.map.getProjectionObject(), "EPSG:4326"); var csv = 'header,reason,start date (yyyy-mm-dd hh:mm),end date (yyyy-mm-dd hh:mm),direction (A to B|B to A|TWO WAY),ignore trafic (Yes|No),segment IDs (id1;id2;...),lon/lat (like in a permalink: lon=xxx&lat=yyy),zoom (2 to 10),MTE id (empty cell if not),comment (optional)\n'; closureList.forEach(function (e) { csv+='add,"' + e.reason + '","' + e.startDate + '","' + e.endDate + '","' + (direction==3?"TWO WAY":(direction==2?"B to A":"A to B")) + '",' + (isIT?"Yes":"No") + ',"' + selection.map(function (s) { return s.attributes.id;}).join(';') + '","lon=' + lonlat.lon + '&lat=' + lonlat.lat + '",' + W.map.zoom + ',' + mteId + ',"Generated by WMEAC"\n'; }); if (!selectionReversed.length==0) { closureList.forEach(function (e) { csv+='add,"' + e.reason + '","' + e.startDate + '","' + e.endDate + '","' + (direction==3?"TWO WAY":(direction==2?"A to B":"B to A")) + '",' + (isIT?"Yes":"No") + ',"' + selectionReversed.map(function (s) { return s.attributes.id;}).join(';') + '","lon=' + lonlat.lon + '&lat=' + lonlat.lat + '",' + W.map.zoom + ',' + mteId + ',"Generated by WMEAC"\n'; }); } WMEAC.download(csv, 'closures.csv'); }); } e=WMEAC.getId('wmeac-advanced-closure-dialog-close-button'); if (e) { e.addEventListener('click', function() { var d = WMEAC.getId('wmeac-add-advanced-closure-dialog'); if (d) { W.selectionManager.events.unregister("selectionchanged", null, WMEAC.refreshClosureList); W.selectionManager.events.unregister("selectionchanged", null, WMEAC.refreshClosureListFromSelection); d.style.display='none'; } }); } e=WMEAC.getId('wmeac-advanced-closure-dialog-apply-button'); if (e) { e.addEventListener('click', function() { var rc = WMEAC.buildClosuresListFromRecurringUI(); if (rc.error!="") { alert("Can't apply closures.\nPlease, check all parameters."); return; } if (W.selectionManager.getSelectedFeatures().length==0 || W.selectionManager.getSelectedFeatures()[0].model.type!="segment") { alert("Please, select segment(s) before."); return; } if (W.selectionManager.getSelectedFeatures().every(function (e) { return e.model.isAllowed(e.model.permissionFlags.EDIT_CLOSURES); })==false) { alert("You don't have permission to edit closures on all those segments."); return; } var reason = $('#wmeac-advanced-closure-dialog-reason').val(); //var cllocation = $('#wmeac-advanced-closure-dialog-location').val(); var direction = $('#wmeac-advanced-closure-dialog-direction').val(); var sc = WMEAC.WMEAPI.require("Waze/Modules/Closures/Models/SharedClosure"); direction=(direction=="1"?WMEAC.sharedClosureDirection.A_TO_B:(direction=="2"?WMEAC.sharedClosureDirection.B_TO_A:WMEAC.sharedClosureDirection.TWO_WAY)); var directionStr = direction==1?"(A → B)":(direction==2?"(B → A)":"(⇆)"); var isIT = $('#wmeac-advanced-closure-dialog-ignoretraffic').is(':checked'); var mte = W.model.majorTrafficEvents.getObjectById($("#wmeac-advanced-closure-dialog-mteid").val()); closureList = rc.list.map(function (e) { //return {reason: reason, direction: direction, startDate: e.start, endDate: e.end, location: cllocation, permanent: isIT}; var details = {reason: reason, direction: direction, startDate: e.start, endDate: e.end, location: "", permanent: isIT}; if (mte) details.eventId = mte.id; return details; }); // save selection list var selection = _.map(W.selectionManager.getSelectedFeatures(), 'model'); W.selectionManager.events.unregister("selectionchanged", null, WMEAC.refreshClosureList); WMEAC.addClosureListFromSelection(closureList, function (i, e) { $('#wmeac-advanced-closure-dialog-preview-' + i).html(e).css({color: "#44D544"}); }, function (i, e) { $('#wmeac-advanced-closure-dialog-preview-' + i).html(e).css({color: "#D5444F"}); }, function () { W.selectionManager.setSelectedModels(selection); //alert ('done'); var tmp = function selectionReady() { if (W.selectionManager.getSelectedFeatures().length==0) window.setTimeout(selectionReady, 500); else { W.selectionManager.events.register("selectionchanged", null, WMEAC.refreshClosureList); $('a[href="#segment-edit-closures"]').click(); } }; window.setTimeout(tmp, 500); }, 0); }); } if (typeof $.fn.datepicker !== 'undefined') $("#wmeac-advanced-closure-dialog-rangestartdate,#wmeac-advanced-closure-dialog-rangeenddate").datepicker({ format: "yyyy-mm-dd", todayHighlight: !0, autoclose: !0}); else if (typeof $.fn.daterangepicker !== 'undefined') // WME beta $("#wmeac-advanced-closure-dialog-rangestartdate,#wmeac-advanced-closure-dialog-rangeenddate").daterangepicker({singleDatePicker: !0, locale: { format: "YYYY-MM-DD" }}); $("#wmeac-advanced-closure-dialog-rangestartdate,#wmeac-advanced-closure-dialog-rangeenddate").on("change", function () { WMEAC.refreshMTEList(); }); $("#wmeac-advanced-closure-dialog-starttime,#wmeac-advanced-closure-dialog-durationtime").timepicker({ defaultTime: "00:00", showMeridian: !1, template: !1}); $("#wmeac-add-advanced-closure-dialog").find(".input-group").find(".input-group-addon").on("click", function (e) { $(e.target).parent().find("input").focus(); }).find("i").on("click", function (e) { $(e.target).parent().parent().find("input").focus(); }); $('#wmeac-advanced-closure-dialog-each-dayall').on('click', function () { var atLeastOneChecked=false; for (var i=0; i<7; i++) atLeastOneChecked = atLeastOneChecked || $("#wmeac-advanced-closure-dialog-each-"+i).is(':checked'); for (var i=0; i<7; i++) $("#wmeac-advanced-closure-dialog-each-"+i).prop('checked', !atLeastOneChecked); $('#wmeac-advanced-closure-dialog-each-dayall').prop('checked', !atLeastOneChecked); }); if (typeof $.fn.spinner !== 'undefined') { $('#wmeac-advanced-closure-dialog-repeat-every-day').spinner({ min: 0, spin: function (event, ui) { $(this).trigger('change'); } }); $('#wmeac-advanced-closure-dialog-repeat-every-hour').spinner({ min: 0, spin: function (event, ui) { if (ui.value >= 24) { $(this).spinner('value', ui.value - 24); $('#wmeac-advanced-closure-dialog-repeat-every-day').spinner('stepUp'); return false; } else if (ui.value < 0) { $(this).spinner('value', ui.value + 24); $('#wmeac-advanced-closure-dialog-repeat-every-day').spinner('stepDown'); return false; } $(this).trigger('change'); } }); $('#wmeac-advanced-closure-dialog-repeat-every-minute').spinner({ spin: function (event, ui) { if (ui.value >= 60) { $(this).spinner('value', ui.value - 60); $('#wmeac-advanced-closure-dialog-repeat-every-hour').spinner('stepUp'); return false; } else if (ui.value < 0) { $(this).spinner('value', ui.value + 60); $('#wmeac-advanced-closure-dialog-repeat-every-hour').spinner('stepDown'); return false; } $(this).trigger('change'); }, change: function (event) { if (event.target.value<0 || event.target.value>59) $(this).spinner('value', 0); } }); $('#wmeac-advanced-closure-dialog-duration-day').spinner({ min: 0, spin: function (event, ui) { $(this).trigger('change'); } }); // $('#wmeac-advanced-closure-dialog-duration-hour').spinner({ // min: 0, // spin: function (event, ui) { // $(this).trigger('change'); // } // }); // $('#wmeac-advanced-closure-dialog-duration-minute').spinner({ // spin: function (event, ui) { // if (ui.value >= 60) { // $(this).spinner('value', ui.value - 60); // $('#wmeac-advanced-closure-dialog-duration-hour').spinner('stepUp'); // return false; // } else if (ui.value < 0) { // $(this).spinner('value', ui.value + 60); // $('#wmeac-advanced-closure-dialog-duration-hour').spinner('stepDown'); // return false; // } // $(this).trigger('change'); // }, // change: function (event) { // if (event.target.value<0 || event.target.value>59) // $(this).spinner('value', 0); // } // }); } $('#wmeac-advanced-closure-dialog-repeat,#wmeac-advanced-closure-dialog-each,#wmeac-advanced-closure-dialog-holiday').on('click', function(e){ window.setTimeout(WMEAC.refreshClosureList); }); $('#wmeac-advanced-closure-dialog-holiday-refresh').on('click', function (e) { var hDiv = $('#wmeac-advanced-closure-dialog-holiday-list'); $('#wmeac-advanced-closure-dialog-holiday-refresh-spinner').css({display: 'block'}); WMEAC.removeChildElements(hDiv[0]); window.setTimeout(function () { WMEAC.getHolidays({ rangeStart: $('#wmeac-advanced-closure-dialog-rangestartdate').val(), rangeEnd: $('#wmeac-advanced-closure-dialog-rangeenddate').val(), countries: _.map(WMEAC.getCountriesFromSegmentSet(_.map(W.selectionManager.getSelectedFeatures(), 'model')), 'abbr'), handlerFinished: function (holidays) { WMEAC.lastGeneratedHolidays = holidays; if (holidays.length==0) hDiv.html("No holiday found."); else { holidays.forEach(function (h, i) { var chkBx = WMEAC.createElement({type: "div", className: "checkbox"}); chkBx.innerHTML='\ '; $(chkBx).on('click', function(e){ window.setTimeout(WMEAC.refreshClosureList); }); hDiv.append(chkBx); }); } $('#wmeac-advanced-closure-dialog-holiday-refresh-spinner').css({display: 'none'}); } }); }); }); $('#wmeac-add-advanced-closure-dialog').on('change', function(e){ window.setTimeout(WMEAC.refreshClosureList); }); WMEAC.reloadPresets(); $('#wmeac-advanced-closure-dialog-presets-load').on('click', function(e){ var presetIndex = parseInt($("#wmeac-advanced-closure-dialog-presets-list").val()); $("#wmeac-advanced-closure-dialog-starttime").val(WMEAC.presets[presetIndex].values.starttime); // $("#wmeac-advanced-closure-dialog-duration-hour").val(WMEAC.presets[presetIndex].values.duration.hour); // $("#wmeac-advanced-closure-dialog-duration-minute").val(WMEAC.presets[presetIndex].values.duration.minute); if (WMEAC.presets[presetIndex].values.duration.hasOwnProperty('day')) $("#wmeac-advanced-closure-dialog-duration-day").val(WMEAC.presets[presetIndex].values.duration.day); else $("#wmeac-advanced-closure-dialog-duration-day").val(Math.floor(WMEAC.presets[presetIndex].values.duration.hour/24)); $("#wmeac-advanced-closure-dialog-durationtime").val('' + (WMEAC.presets[presetIndex].values.duration.hour%24) + ':' + WMEAC.presets[presetIndex].values.duration.minute); $("#wmeac-advanced-closure-dialog-reason").val(WMEAC.presets[presetIndex].values.description); //$("#wmeac-advanced-closure-dialog-location").val(WMEAC.presets[presetIndex].values.location); $("#wmeac-advanced-closure-dialog-direction").val(WMEAC.presets[presetIndex].values.direction); $("#wmeac-advanced-closure-dialog-ignoretraffic").prop('checked', WMEAC.presets[presetIndex].values.ignoretraffic); $("#wmeac-advanced-closure-dialog-repeat-ntimes").val(WMEAC.presets[presetIndex].values.repeat.ntimes); if (WMEAC.presets[presetIndex].values.repeat.hasOwnProperty('day')) $("#wmeac-advanced-closure-dialog-repeat-every-day").val(WMEAC.presets[presetIndex].values.repeat.day); else $("#wmeac-advanced-closure-dialog-repeat-every-day").val(Math.floor(WMEAC.presets[presetIndex].values.repeat.hour/24)); $("#wmeac-advanced-closure-dialog-repeat-every-hour").val(WMEAC.presets[presetIndex].values.repeat.hour%24); $("#wmeac-advanced-closure-dialog-repeat-every-minute").val(WMEAC.presets[presetIndex].values.repeat.minute); for (var i=0; i<7; i++) $("#wmeac-advanced-closure-dialog-each-"+i).prop('checked', WMEAC.presets[presetIndex].values.each[i]); }); $('#wmeac-advanced-closure-dialog-presets-load-fromseg').on('click', function () { closureId = $("#wmeac-advanced-closure-dialog-segclosure-list").val(); if (closureId) { var c = W.model.roadClosures.objects[closureId]; if (c) { $("#wmeac-advanced-closure-dialog-starttime").val(c.startDate.split(' ')[1]); var duration=new Date(c.endDate) - new Date(c.startDate); // $("#wmeac-advanced-closure-dialog-duration-hour").val(Math.floor(duration/3600000)); // $("#wmeac-advanced-closure-dialog-duration-minute").val(new Date(duration).getMinutes()); var days = Math.floor(duration/86400000); $("#wmeac-advanced-closure-dialog-duration-day").val(days); var hours = Math.floor((duration - days * 86400000)/3600000); var minutes = Math.floor((duration - days * 86400000 - hours * 3600000)/60000); $("#wmeac-advanced-closure-dialog-durationtime").val('' + hours + ':' + minutes); $("#wmeac-advanced-closure-dialog-reason").val(c.reason.trim()); if (WMEAC.getOppositeClosure(c).length==0) // oneway $("#wmeac-advanced-closure-dialog-direction").val(c.forward?1:2); else $("#wmeac-advanced-closure-dialog-direction").val(3); $("#wmeac-advanced-closure-dialog-ignoretraffic").prop('checked', c.permanent); // MTE if (c.eventId!=null) { var options = []; $("#wmeac-advanced-closure-dialog-mteid option").each(function () { options.push($(this).val()); }); if (options.indexOf(c.eventId)!=-1) $("#wmeac-advanced-closure-dialog-mteid").val(c.eventId); else $("#wmeac-advanced-closure-dialog-mteid").val(''); } } } }); $('#wmeac-advanced-closure-dialog-presets-delete').on('click', function(e){ var presetIndex = parseInt($("#wmeac-advanced-closure-dialog-presets-list").val()); WMEAC.presets.splice(presetIndex, 1); WMEAC.save(); WMEAC.reloadPresets(); }); $('#wmeac-advanced-closure-dialog-presets-save').on('click', function(e){ var name = $("#wmeac-advanced-closure-dialog-presets-name").val(); var presetIndex = WMEAC.presets.findIndex(function (e) { return e.name==name; }); var preset = {name: name, values: { duration: {}, repeat: {}, each: []}}; if (presetIndex!=-1) // overwrite existing preset preset=WMEAC.presets[presetIndex]; preset.values.starttime=$("#wmeac-advanced-closure-dialog-starttime").val(); preset.values.duration.day=$("#wmeac-advanced-closure-dialog-duration-day").val(); preset.values.duration.hour=parseInt($("#wmeac-advanced-closure-dialog-durationtime").val().split(':')[0]); preset.values.duration.minute=parseInt($("#wmeac-advanced-closure-dialog-durationtime").val().split(':')[1]); preset.values.description=$("#wmeac-advanced-closure-dialog-reason").val(); //preset.values.location=$("#wmeac-advanced-closure-dialog-location").val(); preset.values.direction=$("#wmeac-advanced-closure-dialog-direction").val(); preset.values.ignoretraffic=$("#wmeac-advanced-closure-dialog-ignoretraffic").is(':checked'); preset.values.repeat.ntimes=$("#wmeac-advanced-closure-dialog-repeat-ntimes").val(); preset.values.repeat.day=$("#wmeac-advanced-closure-dialog-repeat-every-day").val(); preset.values.repeat.hour=$("#wmeac-advanced-closure-dialog-repeat-every-hour").val(); preset.values.repeat.minute=$("#wmeac-advanced-closure-dialog-repeat-every-minute").val(); for (var i=0; i<7; i++) preset.values.each[i]=$("#wmeac-advanced-closure-dialog-each-"+i).is(':checked'); if (presetIndex==-1) WMEAC.presets.push(preset); WMEAC.save(); WMEAC.reloadPresets(); }); WMEAC.setDraggable($('#wmeac-add-advanced-closure-dialog'), { controller: $('#wmeac-add-advanced-closure-dialog h1:first-child'), container: [$('#OpenLayers_Map_200_OpenLayers_ViewPort'), $('#WazeMap')] }); }; WMEAC.connectAdvancedClosureTabHandlers = function () { var e = null; e=WMEAC.getId('wmeac-csv-file'); if (e) e.addEventListener('change', WMEAC.CSVFileChanged); e=WMEAC.getId('wmeac-csv-closures-controls-check'); if (e) e.addEventListener('change', function (e) { WMEAC.CSVCheckAll(e.target.checked); }); e=WMEAC.getId('wmeac-csv-closures-controls-apply'); if (e) e.addEventListener('click', WMEAC.CSVApplyChecked); e=WMEAC.getId('wmeac-csv-closures-controls-segs'); if (e) e.addEventListener('click', WMEAC.CSVCheckSegsChecked); }; WMEAC.reloadPresets = function () { var optionList=WMEAC.presets.map(function (p, i) { return ''; }); $("#wmeac-advanced-closure-dialog-presets-list").html(optionList.join('')); }; /*********************************************** *** END OF INCLUDED FILE : *** *** include/setupUI.js *** ***********************************************/ /*********************************************** *** IN INCLUDED FILE : *** *** include/class.progressBar.js *** ***********************************************/ WMEAC.ProgressBar = function (id) { this.id=id; this.divpbi = WMEAC.createElement({type: 'div', id: id, className: id}); var elt = WMEAC.createElement({type: 'div', id: 'wmeac-progressBar'}); elt.style.width="100%"; elt.style.display="none"; elt.innerHTML='
100%'; this.divpbi.appendChild(elt); elt = WMEAC.createElement({type: 'div', id: 'wmeac-progressBar-info'}); //elt.innerHTML=" "; this.divpbi.appendChild(elt); this.isShown = function () { return (this.divpbi.style.display != "none"); }; this.show = function(toShow) { this.divpbi.style.display = (toShow?"block":"none"); }; this.update = function(value) { if (value==-1) { this.divpbi.children[0].style.display='none'; this.divpbi.children[1].style.display='none'; return; } value = Math.round(value); this.divpbi.children[0].style.display='block'; this.divpbi.children[1].style.display='block'; this.divpbi.children[0].children[0].style.width = value+"%"; this.divpbi.children[0].children[1].innerHTML = value+"%"; }; this.info = function(text) { this.divpbi.children[1].innerHTML=text; }; }; /*********************************************** *** END OF INCLUDED FILE : *** *** include/class.progressBar.js *** ***********************************************/ /*********************************************** *** IN INCLUDED FILE : *** *** include/class.closure.js *** ***********************************************/ WMEAC.ClassClosure = function (options) { WMEAC.log("options", options); this.isValid=false; this.errorMessage=''; var validProperties=['reason', 'startDate', 'endDate', 'direction', 'segIDs', 'lonlat', 'permanent', 'id', 'zoom']; var goodOptions=0; validProperties.forEach(function (p) { if (options.hasOwnProperty(p)) { this[p]=options[p]; goodOptions++; } else { this.errorMessage+="Missing property " + p + "\n"; } }, this); if (goodOptions==validProperties.length) { this.isValid=true; } else { return; } // optional options: this.comment=""; if (options.hasOwnProperty('comment')) this.comment=options.comment; this.eventId=null; if (options.hasOwnProperty('eventId') && options.eventId!='') this.eventId=options.eventId; this.segIDs = this.segIDs.split(';'); var matches = this.lonlat.match(/lon=(-?\d+\.?\d*)&lat=(-?\d+\.?\d*)/); if (matches && matches.length==3) this.lonlat = {lon: parseFloat(matches[1]), lat: parseFloat(matches[2])}; else { matches = this.lonlat.match(/lat=(-?\d+\.?\d*)&lon=(-?\d+\.?\d*)/); if (matches && matches.length==3) this.lonlat = {lon: parseFloat(matches[2]), lat: parseFloat(matches[1])}; else { this.isValid=false; this.errorMessage="Can't parse lonlat: " + this.lonlat + "\n"; return; } } if (this.direction!="A to B" && this.direction!="B to A" && this.direction!="TWO WAY") { this.isValid=false; this.errorMessage="Can't determine direction: " + this.direction + "\n"; return; } this.zoom = parseInt(this.zoom); if (this.zoom<14||this.zoom>22) { this.isValid=false; this.errorMessage="Wrong zoom (14 to 22): " + this.zoom + "\n"; return; } this.applyInWME = function(successHandler, failureHandler) { // check if segments are on screen var segs = WMEAC.segmentsIDsToSegments(this.segIDs); WMEAC.log("Segs: ", segs); segs = segs.filter(function (seg) { return seg.isAllowed(seg.permissionFlags.EDIT_CLOSURES); }); if (segs.length==0) { failureHandler([{attributes: {details: "No segment. Check permissions or existence."}}]); } else { var cityStreets = WMEAC.getCityStreetsFromSegmentSet(segs); var closureLocation = Object.keys(cityStreets).map(function (c) { return (Object.keys(cityStreets[c]).map(function (s) { if (s=='noStreet') return I18n.translations[I18n.locale].edit.address.no_street; return s; }).join(', ') + (c=='noCity'?'':' (' + c + ')')); }).join(' ; '); var sc = WMEAC.WMEAPI.require("Waze/Modules/Closures/Models/SharedClosure"); var closureDetails = {reason: this.reason, direction: (this.direction=="A to B"?WMEAC.sharedClosureDirection.A_TO_B:(this.direction=="B to A"?WMEAC.sharedClosureDirection.B_TO_A:WMEAC.sharedClosureDirection.TWO_WAY)), startDate: this.startDate, endDate: this.endDate, location: closureLocation, permanent: this.permanent=='Yes', segments: segs}; if (this.eventId!=null) closureDetails.eventId = this.eventId; WMEAC.addClosure(closureDetails, successHandler, failureHandler); } }; this.removeInWME = function(successHandler, failureHandler) { var segs = WMEAC.segmentsIDsToSegments(this.segIDs); segs = segs.filter(function (seg) { return seg.isAllowed(seg.permissionFlags.EDIT_CLOSURES); }); var allClosuresToRemove=[]; var countToMatch=this.segIDs.length*(this.direction=="TWO WAY"?2:1); // two way = 2 closures in WME segs.forEach(function (s) { // look for closure(s) var that = this; var closures = W.model.roadClosures.getObjectArray(function (c) { return (c.startDate==that.startDate && c.endDate==that.endDate && c.reason.trim()==that.reason && c.segID==s.attributes.id && c.permanent == (that.permanent=='Yes')); }); if ((this.direction=="TWO WAY") || // && closures.length==2 && closures[0].forward!=closures[1].forward) || (this.direction=="A to B" && closures.length==1 && closures[0].forward==true) || (this.direction=="B to A" && closures.length==1 && closures[0].forward==false)) { allClosuresToRemove=allClosuresToRemove.concat(closures); } }, this); if (allClosuresToRemove.length==0) { failureHandler([{attributes: {details: "No segment. Check permissions or existence."}}]); } else WMEAC.removeClosure(allClosuresToRemove, successHandler, failureHandler); }; }; /*********************************************** *** END OF INCLUDED FILE : *** *** include/class.closure.js *** ***********************************************/ /*********************************************** *** IN INCLUDED FILE : *** *** include/recurringClosures.js *** ***********************************************/ WMEAC.buildClosuresListFromRecurringUI = function () { var list = []; var rangeStartDate = new JDate($('#wmeac-advanced-closure-dialog-rangestartdate').val()); if (!WMEAC.isValidDate(rangeStartDate)) return {list: list, error: "Range start date is not valid"}; var rangeEndDate = new JDate($('#wmeac-advanced-closure-dialog-rangeenddate').val()); if (!WMEAC.isValidDate(rangeEndDate)) return {list: list, error: "Range end date is not valid"}; if (rangeEndDate=60) return {list: list, error: "Duration minute is invalid"}; var dH = parseInt($('#wmeac-advanced-closure-dialog-durationtime').val().split(':')[0]); var dM = parseInt($('#wmeac-advanced-closure-dialog-durationtime').val().split(':')[1]); if (dD==0 && dH==0 && dM==0) return {list: list, error: "Duration is null"}; // var rangeStartTimeM = $('#wmeac-advanced-closure-dialog-rangestarttime').val().split(':').map(function (e) { // return parseInt(e); // }).reduce(function (p, c, i) { // return (p*60+c); // }); var rangeStartTimeM = 0; // var rangeEndTimeM = $('#wmeac-advanced-closure-dialog-rangeendtime').val().split(':').map(function (e) { // return parseInt(e); // }).reduce(function (p, c, i) { // return (p*60+c); // }); var rangeEndTimeM = 1440; var rangeEndDateTime = rangeEndDate.clone(); rangeEndDateTime.addMinutes(rangeEndTimeM); var startTimeM = $('#wmeac-advanced-closure-dialog-starttime').val().split(':').map(function (e) { return parseInt(e); }).reduce(function (p, c, i) { return (p*60+c); }); // if mode is REPEAT if ($('#wmeac-advanced-closure-dialog-tabrepeat').attr('class').indexOf('active')!=-1) { var ntimes = parseInt($('#wmeac-advanced-closure-dialog-repeat-ntimes').val()); if (isNaN(ntimes) || ntimes<1) return {list: list, error: "Repeat count is invalid"}; var evD = parseInt($('#wmeac-advanced-closure-dialog-repeat-every-day').val()); if (isNaN(evD) || evD<0) return {list: list, error: "Repeat every day is invalid"}; var evH = parseInt($('#wmeac-advanced-closure-dialog-repeat-every-hour').val()); if (isNaN(evH) || evH<0) return {list: list, error: "Repeat every hour is invalid"}; var evM = parseInt($('#wmeac-advanced-closure-dialog-repeat-every-minute').val()); if (isNaN(evM) || evM<0 || evM>=60) return {list: list, error: "Repeat every minute is invalid"}; // if repeat is smaller than duration if (evD * 1440 + evH * 60 + evM < dD * 1440 + dH * 60 + dM) return {list: list, error: "Repeat must be greater than duration"}; var firstDateTimeStart = rangeStartDate.clone(); if (startTimeM rangeEndDateTime) // stop if after range end break; // WMEAC.log('end', end); // WMEAC.log('now', now); // if (end < now) // do not add closure that ends before now // { // ntimes++; // continue; // } list.push({start: WMEAC.dateToClosureStr(start), end: WMEAC.dateToClosureStr(end)}); } return {list: list, error: ""}; } // if mode is EACH else if ($('#wmeac-advanced-closure-dialog-tabeach').attr('class').indexOf('active')!=-1) { // build bits for a week: var dow = WMEAC.daysOfWeek.map(function (e, i) { return ($('#wmeac-advanced-closure-dialog-each-' + i)).is(':checked'); }); var dayCount = Math.ceil((rangeEndDate-rangeStartDate+1)/86400000); var day0 = rangeStartDate.clone(); day0.addMinutes(startTimeM); if (startTimeM rangeEndDateTime) // stop if after range end break; list.push({start: WMEAC.dateToClosureStr(start), end: WMEAC.dateToClosureStr(end)}); } } return {list: list, error: ""}; } else if ($('#wmeac-advanced-closure-dialog-tabholiday').attr('class').indexOf('active')!=-1) { WMEAC.lastGeneratedHolidays.forEach(function (e, i) { if (($('#wmeac-advanced-closure-dialog-holidays-' + i)).is(':checked')) { var start = new JDate(e.date).addMinutes(startTimeM); var end = start.clone(); end.addMinutes(dD * 1440 + dH * 60 + dM); list.push({start: WMEAC.dateToClosureStr(start), end: WMEAC.dateToClosureStr(end)}); } }); return {list: list, error: ""}; } else return {list: list, error: "Wrong tab active"}; }; WMEAC.refreshClosureList = function () { try { var rc = WMEAC.buildClosuresListFromRecurringUI(); if (rc.error!="") $('#wmeac-csv-closures-preview-content').html(rc.error); else { var reason = $('#wmeac-advanced-closure-dialog-reason').val(); //var cllocation = $('#wmeac-advanced-closure-dialog-location').val(); var direction = $('#wmeac-advanced-closure-dialog-direction').val(); var directionStr = direction==1?"(A → B)":(direction==2?"(B → A)":"(⇆)"); var isIT = $('#wmeac-advanced-closure-dialog-ignoretraffic').is(':checked'); var existingClosures = W.selectionManager.getSelectedFeatures().reduce(function (p, c, i) { var revSegs = W.selectionManager.getReversedSegments(); var isReversed = revSegs.hasOwnProperty(c.model.attributes.id) && revSegs[c.model.attributes.id]; var realWay = isReversed?(direction==1?2:1):direction; return p.concat(W.model.roadClosures.getObjectArray(function (e) { return (e.segID==c.model.attributes.id && (direction==3 || (e.forward && realWay==1) || (!e.forward && realWay==2))); })); }, []); var mte = W.model.majorTrafficEvents.getObjectById($("#wmeac-advanced-closure-dialog-mteid").val()); $('#wmeac-csv-closures-preview-content').html('' + rc.list.length + ' closure(s) to apply:
' + rc.list.map(function (e, i) { var overlap = existingClosures.filter(function (c) { return WMEAC.dateTimeOverlaps({startDate: e.start, endDate: e.end}, c); }).map(function (c) { var msg = (c.reason?c.reason + ' ':'') + '(' + c.segID + ')'; if (W.model.segments.objects.hasOwnProperty(c.segID)==false) return msg; if (W.model.segments.objects[c.segID].attributes.primaryStreetID==null) return msg; if (W.model.streets.objects.hasOwnProperty(W.model.segments.objects[c.segID].attributes.primaryStreetID)==false) return msg; var street = W.model.streets.objects[W.model.segments.objects[c.segID].attributes.primaryStreetID]; if (!street.isEmpty) msg = street.name + ': ' + msg; return msg; }); var mteOK=!(mte && (new Date(e.start) < new Date(mte.attributes.startDate) || new Date(e.end) > new Date(mte.attributes.endDate))); return (reason + //' (' + cllocation + '): ' + ': ' + e.start + ' → ' + e.end + ' ' + directionStr + ' ' + (overlap.length!=0?' ':'') + (mteOK?'':' ') + ' '); }).join('
')); } } catch (e) { WMEAC.logError("Error while refreshing closure list: ", e); } }; WMEAC.refreshMTEList = function () { var currentMTEid = $("#wmeac-advanced-closure-dialog-mteid").val(); var rangeStart = new JDate($("#wmeac-advanced-closure-dialog-rangestartdate").val()); var rangeEnd = new JDate($("#wmeac-advanced-closure-dialog-rangeenddate").val()); var options=[{name: 'none', value: ''}]; $("#wmeac-advanced-closure-dialog-mteid").empty(); if (WMEAC.isValidDate(rangeStart) && WMEAC.isValidDate(rangeEnd)) { rangeEnd.addDays(1); // filter MTE loaded in WME: W.model.majorTrafficEvents.getObjectArray(function (mte) { // check if ranges overlap return (WMEAC.dateTimeOverlaps({startDate: rangeStart, endDate: rangeEnd}, {startDate: new JDate(mte.attributes.startDate), endDate: new JDate(mte.attributes.endDate)})); }).forEach(function (mte) { options.push({name: mte.attributes.names[0].value, value: mte.attributes.id}); }); } options.forEach(function (o) { var el = WMEAC.createElement({type: 'option'}); el.setAttribute('value', o.value); if (currentMTEid==o.value) el.setAttribute('selected', ''); el.innerHTML = o.name; $("#wmeac-advanced-closure-dialog-mteid").append(el); }); if (options.length>1) $("#wmeac-advanced-closure-dialog-mteid").removeAttr('disabled'); else $("#wmeac-advanced-closure-dialog-mteid").attr('disabled', ''); }; WMEAC.refreshClosureListFromSelection = function () { try { var currentSegClosure = $("#wmeac-advanced-closure-dialog-segclosure-list").val(); $("#wmeac-advanced-closure-dialog-segclosure-list").empty(); if (W.selectionManager.getSelectedFeatures().length!=0) { var blackList=[]; W.model.roadClosures.getObjectArray(function (c) { return c.segID==W.selectionManager.getSelectedFeatures()[0].model.attributes.id; }).sort(function (a,b) { return (new Date(a.startDate)-new Date(b.startDate)); }).forEach(function (c) { if (blackList.indexOf(c.id)!=-1) return; var direction = c.forward?"A to B":"B to A"; var oppositeClosure = WMEAC.getOppositeClosure(c); if (!oppositeClosure.length==0) { direction = "Two way"; blackList.push(oppositeClosure[0].id); } var el = WMEAC.createElement({type: 'option'}); el.setAttribute('value', c.id); if (currentSegClosure==c.id) el.setAttribute('selected', ''); el.innerHTML = c.reason.trim() + ' ' + direction + ' ' + c.startDate + '→' + c.endDate; $("#wmeac-advanced-closure-dialog-segclosure-list").append(el); }); } } catch (e) { WMEAC.logError("Error while refreshing closure list from selection: ", e); } }; /*********************************************** *** IN INCLUDED FILE : *** *** include/holidays.js *** ***********************************************/ WMEAC.abbrToISO3166_1alpha2 = function (abbr) { switch(abbr) { case 'GM': return 'DE'; break; case 'BU': return 'BG'; break; case 'EZ': return 'CZ'; break; case 'SP': return 'ES'; break; case 'UK': return 'GB'; break; case 'LO': return 'SK'; break; default: return abbr; break; } return abbr; }; WMEAC.getHolidays = function (options) { var holidays = []; var currentCountryIndex = 0; var rangeStart = new JDate(options.rangeStart); var rangeEnd = new JDate(options.rangeEnd).addDays(1); var years = []; for (y=parseInt(options.rangeStart.substring(0,4)); y<=parseInt(options.rangeEnd.substring(0,4)); y++) years.push(y); var currentYearIndex = 0; var tmp1 = function downloadNext() { if (currentCountryIndex>=options.countries.length) if (options.handlerFinished) { holidays.sort(function (a, b) { return (new Date(a.date)-new Date(b.date)); }); holidays=holidays.filter(function (h, i) { if (i!=0) { if (holidays[i-1].date==h.date) { holidays[i-1].name += ' / ' + h.name; holidays[i-1].country += ' / ' + h.country; return false; } } return true; }); options.handlerFinished(holidays); return; } window.WMEAC_downloadHelper.add( //"https://holidayapi.com/v1/holidays?country=" + WMEAC.abbrToISO3166_1alpha2(options.countries[currentCountryIndex]) + "&year=" + dateToNext.substring(0, 4) + "&month=" + dateToNext.substring(5, 7) + "&day=" + dateToNext.substring(8) + "&upcoming", "https://holidayapi.com/v1/holidays?key=ca1a7925-0045-47da-bcf6-ee0de583e384&country=" + WMEAC.abbrToISO3166_1alpha2(options.countries[currentCountryIndex]) + "&year=" + years[currentYearIndex], function (data) { if (data.status=='success') { try { nextHoliday = JSON.parse(data.data); if (nextHoliday.hasOwnProperty('holidays')) { for (var hd in nextHoliday.holidays) { if (!nextHoliday.holidays.hasOwnProperty(hd)) continue; if (nextHoliday.holidays[hd].length==0) continue; var name = _.map(nextHoliday.holidays[hd], 'name').join(' / '); var h = nextHoliday.holidays[hd][0]; var d = new Date(h.date); if (d>=rangeStart && d=closureList.length) { WMEAC.reloadClosuresLayer(function () { if (endHandler) endHandler(); }); return; } var c=closureList[i]; var fail = function (e) { return function (f) { if (failureHandler) { var details = []; f.errors.forEach(function (err) { if (err.hasOwnProperty('attributes') && err.attributes.hasOwnProperty('details')) details.push(err.attributes.details); }); failureHandler(i, details.join (' | ')); } else WMEAC.log("Failed to create closure:", f); WMEAC.addClosureListFromSelection(closureList, successHandler, failureHandler, endHandler, i+1); }; }; var done = function (e) { return function (f) { if (successHandler) { successHandler(i, "OK"); } else WMEAC.log("Closure successful:", f); WMEAC.addClosureListFromSelection(closureList, successHandler, failureHandler, endHandler, i+1); }; }; var cab = WMEAC.WMEAPI.require("Waze/Modules/Closures/Models/ClosureActionBuilder"); var sc = WMEAC.WMEAPI.require("Waze/Modules/Closures/Models/SharedClosure"); var t = {}; var segs = _.map(W.selectionManager.getSelectedFeatures(), 'model'); var cityStreets = WMEAC.getCityStreetsFromSegmentSet(segs); var closureLocation = Object.keys(cityStreets).map(function (c) { return (Object.keys(cityStreets[c]).map(function (s) { if (s=='noStreet') return I18n.translations[I18n.locale].edit.address.no_street; return s; }).join(', ') + (c=='noCity'?'':' (' + c + ')')); }).join(' ; '); var closureDetails = {reason: closureList[i].reason + String.fromCharCode(160), direction: closureList[i].direction, startDate: closureList[i].startDate, endDate: closureList[i].endDate, location: closureLocation, permanent: closureList[i].permanent, segments: segs, reverseSegments: W.selectionManager.getReversedSegments()}; if (closureList[i].hasOwnProperty('eventId') && closureList[i].eventId!=null) closureDetails.eventId = closureList[i].eventId; var c = new sc(closureDetails, {dataModel: W.model, segmentSelection: W.selectionManager.getSegmentSelection(), isNew: true}); t.actions=[cab.add(c)]; W.controller.save(t).then(done()).catch(fail()); }; WMEAC.addClosureFromSelection = function (options, successHandler, failureHandler) { if (options && options.hasOwnProperty('reason') && options.hasOwnProperty('direction') && options.hasOwnProperty('startDate') && options.hasOwnProperty('endDate') && options.hasOwnProperty('location') && options.hasOwnProperty('permanent')) { WMEAC.log("Addinf closure: ", options); var fail = function (e) { return function (f) { if (failureHandler) failureHandler(f); else WMEAC.log("Failed to create closure:", f); }; }; var done = function (e) { return function (f) { if (successHandler) successHandler(f); else WMEAC.log("Closure successful:", f); }; }; var cab = WMEAC.WMEAPI.require("Waze/Modules/Closures/Models/ClosureActionBuilder"); var sc = WMEAC.WMEAPI.require("Waze/Modules/Closures/Models/SharedClosure"); var t = {}; var segs = _.map(W.selectionManager.getSelectedFeatures(), 'model'); var closureDetails = {reason: options.reason + String.fromCharCode(160), direction: options.direction, startDate: options.startDate, endDate: options.endDate, location: options.location, permanent: options.permanent, segments: segs, reverseSegments: W.selectionManager.getReversedSegments()}; if (options.hasOwnProperty('eventId') && options.eventId!=null) closureDetails.eventId = options.eventId; var c = new sc(closureDetails, {dataModel: W.model, segmentSelection: W.selectionManager.getSegmentSelection(), isNew: true}); t.actions=[cab.add(c)]; W.controller.save(t).then(done()).catch(fail()); return true; } return false; }; WMEAC.removeClosure = function (closures, successHandler, failureHandler) { var fail = function (e) { return function (f) { if (failureHandler) failureHandler(f); else WMEAC.log("Failed to delete closure:", f); }; }; var done = function (e) { return function (f) { if (successHandler) successHandler(f); else WMEAC.log("Closure deletion successful:", f); }; }; var cab = WMEAC.WMEAPI.require("Waze/Modules/Closures/Models/ClosureActionBuilder"); var sc = WMEAC.WMEAPI.require("Waze/Modules/Closures/Models/SharedClosure"); var t = {}; var c = new sc({closures: [].concat(closures)}, {dataModel: W.model, segmentSelection: W.selectionManager.getSegmentSelection(), isNew: true}); t.actions=[cab.delete(c)]; W.controller.save(t).then(done()).catch(fail()); return true; }; /*********************************************** *** END OF INCLUDED FILE : *** *** include/actionClosures.js *** ***********************************************/ // functions to load and save settings /*********************************************** *** IN INCLUDED FILE : *** *** include/saveLoad.js *** ***********************************************/ WMEAC.save = function () { WMEAC.log("save data..."); localStorage.WMEAC = JSON.stringify({presets: WMEAC.presets}); }; WMEAC.load = function () { try { var saved = JSON.parse(localStorage.WMEAC); WMEAC.presets = saved.presets; WMEAC.log("presets", WMEAC.presets); } catch (err) { WMEAC.log("Error while loading data from storage: " , err); } }; /*********************************************** *** END OF INCLUDED FILE : *** *** include/saveLoad.js *** ***********************************************/ /*********************************************** *** IN INCLUDED FILE : *** *** include/csv.js *** ***********************************************/ WMEAC.parseCSV = function (csvString) { if (csvString!=null) { var csvArray = WMEAC.CSVtoArray(csvString); WMEAC.log("CSV as array:", csvArray); var isValid = WMEAC.csv[0].validate(csvArray); if (isValid.isValid) { var closures = WMEAC.csv[0].filter(csvArray).map(function (e, i) { return {action: e[0], closure: new WMEAC.ClassClosure({reason:e[1], startDate:e[2], endDate:e[3], direction:e[4], segIDs:e[6], lonlat:e[7], permanent:e[5], zoom: e[8], id: i, eventId: e[9], comment: (e.length==11?e[10]:'')}), UI: null}; }); closures.forEach(function (c) { if (!c.closure.isValid) { isValid.isValid = false; isValid.feedBack += c.closure.errorMessage; } }); } if (isValid.isValid) { WMEAC.log("CSV is valid!"); WMEAC.log("Closure list:", closures); WMEAC.csvCurrentClosureList = closures; var listUI = WMEAC.getId('wmeac-csv-closures-list-elts'); // remove all closures before: WMEAC.removeChildElements(listUI); closures.forEach(function (c) { c.UI = WMEAC.buildInlineClosureUI(c.closure, c.action); listUI.appendChild(c.UI); }); WMEAC.csvShowList(true); WMEAC.csvAddLog("CSV parse successful\n"); return true; // aply closures: TEST ONLY: this should not be done there! /*closures.forEach(function (c) { c.closure.applyInWME(function () { WMEAC.log("Closure success:", c);}); });*/ // END OF aply closures: TEST ONLY: this should not be done there! } else { WMEAC.log("CSV is NOT valid!:" + isValid.feedBack + "\n"); WMEAC.csvAddLog(isValid.feedBack + '\n'); WMEAC.csvShowList(false); WMEAC.csvCurrentClosureList = null; return false; } return false; } return false; }; WMEAC.CSVFileChanged = function (evt) { var files = evt.target.files; // FileList object for (var i = 0, f; f = files[i]; i++) { var reader = new FileReader(); reader.onload = (function(theFile) { return function(e) { WMEAC.log("import CSV file read"); WMEAC.csvClearLog(); if (WMEAC.parseCSV(e.target.result)) { WMEAC.csvCurrentBatchClosureList=WMEAC.csvCurrentClosureList.slice(); // WMEAC.csvCheckAllSegments(-1); } }; })(f); // Read in the image file as a data URL. reader.readAsText(f); } this.value = null; WMEAC.getId('wmeac-csv-closures-controls-check').checked=false; }; WMEAC.ClassCSV = function (options) { this.isValid=false; if (options.hasOwnProperty('version')) this.version=options.version; else return; if (options.hasOwnProperty('regexpValidation')) this.regexpValidation=options.regexpValidation; else return; this.isValid=true; this.validate = function(data) { var regexps = this.regexpValidation; var feedBack = ""; this.filter(data).forEach(function (line, l) { var isLineValid = line.reduce(function (stillValid, cell, i) { var isCellValid = cell.match(regexps[i])!=null; if (!isCellValid) feedBack+="Error while parsing line " + l + " cell " + i + ": \"" + cell + "\" in line " + line.join(','); return (stillValid && isCellValid); }, true); }, this); return {isValid: feedBack=="", feedBack: feedBack}; }; this.filter = function(data) { return data.filter(function (line) { // return (line.length>=1 && line[0]!="header" && line[0]!="comment"); return (line.length>=1 && ['add','remove'].indexOf(line[0])!=-1); }); }; }; WMEAC.csv.push(new WMEAC.ClassCSV({version: 1, regexpValidation: [/.*/, // 1st cell: action is free keyword. It will be filtered later /.*/, // reason is free // /.*/, // location is free /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/, // start date /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/, // end date /(^A to B$)|(^B to A$)|(^TWO WAY$)/, // direction /(Yes)|(No)/, // ignore trafic = permanent /^(\d+(;|$))+/, // seg ID list /(lon=(-?\d+\.?\d*)&lat=(-?\d+\.?\d*))|(lat=(-?\d+\.?\d*)&lon=(-?\d+\.?\d*))/, // lonlat /^\d+$/, // zoom /(^$)|(^-?\d+\.-?\d+\.-?\d+$)/ // MTE ID is empty or digits.digits.digits ]})); WMEAC.buildInlineClosureUI = function (closure, action) { var liElt = WMEAC.createElement({type: 'li', className: 'wmeac-csv-closures-list-' + action}); liElt.setAttribute('closureID', closure.id); liElt.innerHTML='
\
' + closure.reason + '
' + closure.comment + '
\
' + closure.startDate + '
' + closure.endDate + '
\
' + (closure.direction=="A to B"?'A→B':(closure.direction=="B to A"?'B→A':'A↔B')) + '
\
\
\
\
' + (action=='add'?'Ready to apply':(action=='remove'?'Ready to remove':'')) + '
'; // attach handlers liElt.children[5].children[0].addEventListener('click', function (e) { WMEAC.csvClearLog(); // get closure id: var cid = parseInt(e.target.parentNode.parentNode.parentNode.getAttribute('closureID')); var closure = WMEAC.csvCurrentClosureList.find(function (c) { return (c.closure.id==cid); }); WMEAC.log('Closure to target:', closure); var xy = OpenLayers.Layer.SphericalMercator.forwardMercator(closure.closure.lonlat.lon, closure.closure.lonlat.lat); W.map.setCenter(xy, closure.closure.zoom); var tmp3 = function selectSegments() { WMEAC.log("Now select segments..."); var segs = WMEAC.segmentsIDsToSegments(closure.closure.segIDs); if (segs.length!=closure.closure.segIDs.length) { if (segs.length==0) { WMEAC.csvAddLog("No segment found: " + closure.closure.comment + "(" + closure.closure.reason + ")\n"); WMEAC.setCSVMiniLog(closure, "Selection failed: no segment found", 3); } else { WMEAC.csvAddLog("Partial selection (" + segs.length + "/" + closure.closure.segIDs.length + "): " + closure.closure.comment + "(" + closure.closure.reason + ")\n"); WMEAC.setCSVMiniLog(closure, "Partial selection: " + segs.length + "/" + closure.closure.segIDs.length, 2); } alert ("Warning: missing segments.\nFound " + segs.length + "/" + closure.closure.segIDs.length + " segment(s)"); } else { WMEAC.csvAddLog("Selection ok (" + segs.length + "): " + closure.closure.comment + "(" + closure.closure.reason + ")\n"); WMEAC.setCSVMiniLog(closure, "Selection OK: " + segs.length, 1); } if (segs.length!=0) { W.selectionManager.setSelectedModels(segs); var tmp = function selectionReady() { if (W.selectionManager.getSelectedFeatures().length==0) window.setTimeout(selectionReady, 500); else { $('a[href="#segment-edit-closures"]').click(); } }; window.setTimeout(tmp, 500); } }; var tmp2 = function readyToSelect() { WMEAC.log("Test if ready to select..."); if (WMEAC.pendingOps==true) { WMEAC.log("Not yet. Waiting for WME..."); window.setTimeout(readyToSelect, 500); } else { tmp3(); } }; var tmp1 = function mapMovedEnd() { WMEAC.log("Test if roads are reloaded..."); if (WMEAC.pendingOps==true) { WMEAC.log("Not yet. Waiting for WME..."); window.setTimeout(mapMovedEnd, 500); } else { WMEAC.reloadRoadLayer(); tmp2(); } }; window.setTimeout(tmp1, 500); e.preventDefault(); }); liElt.children[6].children[0].addEventListener('click', function (e) { // get closure id: WMEAC.csvClearLog(); var liElt = e.target.parentNode.parentNode.parentNode; var cid = parseInt(liElt.getAttribute('closureID')); var closure = WMEAC.csvCurrentClosureList.find(function (c) { return (c.closure.id==cid); }); WMEAC.log('Closure to apply:', closure); WMEAC.csvApplyClosure(closure, null); }); return liElt; }; WMEAC.csvApplyClosure = function(closure, handler) { var xy = OpenLayers.Layer.SphericalMercator.forwardMercator(closure.closure.lonlat.lon, closure.closure.lonlat.lat); W.map.setCenter(xy, closure.closure.zoom); function applySuccess(evt) { WMEAC.csvAddLog("Closure OK: " + closure.closure.comment + "(" + closure.closure.reason + ")\n"); closure.UI.className="wmeac-csv-closures-list-done"; WMEAC.setCSVMiniLog(closure, "OK", 1); handler && handler(true); }; function applyFailure(evt) { //WMEAC.log('evt', evt); var details=""; evt.errors.forEach(function (err) { if (err.hasOwnProperty('attributes') && err.attributes.hasOwnProperty('details')) details += err.attributes.details + "\n"; }); WMEAC.csvAddLog("Closure KO: " + closure.closure.comment + " (" + closure.closure.reason + ")\n" + details + "\n"); WMEAC.setCSVMiniLog(closure, "KO: " + details, 3); closure.UI.className="wmeac-csv-closures-list-failed"; handler && handler(false); }; var tmp3 = function applyClosure() { WMEAC.log("Now apply closure..."); if (closure.action=="add") closure.closure.applyInWME(applySuccess, applyFailure); else if (closure.action=='remove') closure.closure.removeInWME(applySuccess, applyFailure); }; var tmp2 = function readyToApply() { WMEAC.log("Test if ready to apply..."); if (WMEAC.pendingOps==true) { WMEAC.log("Not yet. Waiting for WME..."); window.setTimeout(readyToApply, 500); } else { tmp3(); } }; var tmp1 = function mapMovedEnd() { WMEAC.log("Test if roads are reloaded..."); if (WMEAC.pendingOps==true) { WMEAC.log("Not yet. Waiting for WME..."); window.setTimeout(mapMovedEnd, 500); } else { WMEAC.reloadRoadLayer(); tmp2(); } }; window.setTimeout(tmp1, 1500); }; WMEAC.csvAddLog = function(text) { var divLog = WMEAC.getId('wmeac-csv-closures-log'); divLog.innerHTML += text.replace(/\n/g, "
"); }; WMEAC.csvClearLog = function() { var divLog = WMEAC.getId('wmeac-csv-closures-log'); divLog.innerHTML = ""; }; WMEAC.csvShowList = function(show) { var divList = WMEAC.getId('wmeac-csv-closures'); divList.style.display=(show?"block":"none"); }; WMEAC.csvCheckAllSegments = function (i) { if (i==-1) // firt call: init progressbar { WMEAC.pb.update(0); WMEAC.pb.show(true); // and call the check on first closure window.setTimeout(function () { WMEAC.csvCheckAllSegments(0); }); return; } var continueSegmentCheck = function() { window.setTimeout(function () { WMEAC.csvCheckAllSegments(i+1); }); }; if (i=1 && marker.model.reason.charCodeAt(marker.model.reason.length-1)==160) marker.icon.$div.addClass('wmeac-hl'); } } catch (e) { WMEAC.log("Highlight error: ", e); } }; /*********************************************** *** END OF INCLUDED FILE : *** *** include/highlight.js *** ***********************************************/ if (typeof window.require != 'undefined' && typeof window.define == 'undefined') // that's the require provided by waze devs { WMEAC.WMEAPI={require: window.require}; // start normally WMEAC.bootstrapAC(); } else { // use the patch. // the patch will call bootstrapAC to start the script /*********************************************** *** IN INCLUDED FILE : *** *** include/requirePatch.js *** ***********************************************/ // setup one global var and put all in var WMEAPI = {}; // detect URL of WME source code WMEAPI.scripts = document.getElementsByTagName('script'); WMEAPI.url=null; for (i=0;i