Last active
December 8, 2021 18:33
-
-
Save musa11971/cb4aba0bdb241ea043af1252c6712d5b to your computer and use it in GitHub Desktop.
Waze Map Editor - Stroopwafel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name WME Stroopwafel | |
// @namespace https://github.com/musa11971 | |
// @version 1.8 | |
// @description Stroopwafel is a userscript for Waze Map Editor that helps editors mark 'edited' areas based on different aspects. | |
// @author musa11971 (Waze: mewsa) - https://github.com/musa11971 | |
// @include /^https:\/\/(www|beta)\.waze\.com\/(?!user\/)(.{2,6}\/)?editor.*$/ | |
// @run-at document-end | |
// @exclude https://www.waze.com/*user/*editor/* | |
// @require https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js | |
// @downloadURL https://gist.github.com/musa11971/cb4aba0bdb241ea043af1252c6712d5b/raw/WME_Stroopwafel.user.js | |
// @icon https://user-images.githubusercontent.com/21341801/118674863-69d1db80-b7fa-11eb-8cbb-4c271874b587.png | |
// @grant none | |
// ==/UserScript== | |
const HTML_GRID_SQUARE_TOOLTIP = "<div id=\"WME-Stroopwafel-GridSquare-Tooltip\"> <span id=\"Current-Grid-Square-Code\"></span> <table id=\"Current-Grid-Square-Aspect-Information\"></table></div><style> #WME-Stroopwafel-GridSquare-Tooltip { display: none; background-color: #eeeeee; color: #000; padding: 10px; border-radius: 6px; position: absolute; z-index: 1; } #WME-Stroopwafel-GridSquare-Tooltip::after { content: \" \"; position: absolute; top: 100%; left: 50%; margin-left: -5px; border-width: 5px; border-style: solid; border-color: #eeeeee transparent transparent transparent; } #Current-Grid-Square-Code { display: block; width: 100%; text-align: center; padding-bottom: 4px; font-weight: bold; }</style>";const HTML_TOAST = "<div id=\"WME_Marker_Toasts\"></div><style> #WME_Marker_Toasts { position: absolute; width: auto; bottom: 60px; right: 120px; } .WME_Marker_Toast_default { color: #fff; background: #979797; } .WME_Marker_Toast_success { color: #000; background: #7fe89f; } .WME_Marker_Toast_danger { color: #fff; background: #c85d5d; } .WME_Marker_Toast { border-radius: 15px; height: 25px; font-size: 20px; padding: 2px 16px; width: max-content; animation: fadeIn ease 1s; -webkit-animation: fadeIn ease 1s; -moz-animation: fadeIn ease 1s; -o-animation: fadeIn ease 1s; } .WME_Marker_Toast + .WME_Marker_Toast { margin-top: 6px; } @keyframes fadeIn { 0% {opacity:0;} 100% {opacity:1;} } @-moz-keyframes fadeIn { 0% {opacity:0;} 100% {opacity:1;} } @-webkit-keyframes fadeIn { 0% {opacity:0;} 100% {opacity:1;} } @-o-keyframes fadeIn { 0% {opacity:0;} 100% {opacity:1;} } @-ms-keyframes fadeIn { 0% {opacity:0;} 100% {opacity:1;} }</style>";const HTML_CONTEXT_MENU = "<div id=\"WME_Marker_Context_Menu\"> <span id=\"WME-Stroopwafel-Context-Close\">✕</span> <p><span id=\"selectionCount\">0</span> tile(s) selected</p> <div id=\"WME_Marker_Context_Spinner\"> <div class=\"lds-ripple\"><div></div><div></div></div> </div> <table id=\"WME_Marker_Context_Aspects\"> <span id=\"WME-Stroopwafel-Context-No-Aspects\">No aspects selected.</span> </table> <div class=\"waze-btn waze-btn-small waze-btn-green\" id=\"WME_Marker_Context_Save_Btn\">Save</div></div><style> #WME_Marker_Context_Menu { position: absolute; display: none; background: white; padding: 0; margin: 0; z-index: 100; border-radius: 3px; -webkit-box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.3); box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.3); -webkit-transform: translate(0, 15px) scale(0.95); transform: translate(0, 15px) scale(0.95); -webkit-transition: opacity 0.1s ease-out, -webkit-transform 0.1s ease-out; transition: opacity 0.1s ease-out, -webkit-transform 0.1s ease-out; transition: transform 0.1s ease-out, opacity 0.1s ease-out; transition: transform 0.1s ease-out, opacity 0.1s ease-out, -webkit-transform 0.1s ease-out; -webkit-touch-callout: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } #WME_Marker_Context_Menu p { display: block; font-size: 15px; padding: 10px 15px; font-weight: bold; margin-right: 40px; } #WME_Marker_Context_Save_Btn { margin: 5px 10px 5px 10px; } #WME_Marker_Context_Spinner { display: none; } #WME-Stroopwafel-Context-Close { display: block; position: absolute; top: 0; right: 0; padding: 8px; cursor: pointer; color: #000; } .lds-ripple { display: block; position: relative; margin: 5px auto; width: 80px; height: 80px; } .lds-ripple div { position: absolute; border: 4px solid #bbb; opacity: 1; border-radius: 50%; animation: lds-ripple 1s cubic-bezier(0, 0.2, 0.8, 1) infinite; } .lds-ripple div:nth-child(2) { animation-delay: -0.5s; } @keyframes lds-ripple { 0% { top: 36px; left: 36px; width: 0; height: 0; opacity: 1; } 100% { top: 0px; left: 0px; width: 72px; height: 72px; opacity: 0; } } #WME_Marker_Context_Aspects { table-layout: fixed; width: 230px; } #WME_Marker_Context_Aspects label { margin-left: 6px; } .waze-btn-empty { border: 1px solid #636f76; background: #fff; color: #fff; } #WME_Marker_Context_Aspects button { display: block; height: 100%; width: 100%; } #WME_Marker_Context_Aspects td:first-child { word-break: normal; width: 200px; } #WME_Marker_Context_Aspects td:nth-child(2) { width: 70px; padding: 4px; } #WME-Stroopwafel-Context-No-Aspects { font-weight: bold; display: none; margin: 6px auto; text-align: center; }</style>";const HTML_MODAL_FEEDBACK = "<div> <h2>Feedback</h2> <p>We are constantly trying to improve WME Stroopwafel. If you have feedback, be it a compliment, complaint or a feature request. You are welcome to reply to the public <a href=\"https://www.waze.com/forum/viewtopic.php?f=819&t=317904\" target=\"_blank\">Stroopwafel forum thread</a>. </p> <h2>Grid issues</h2> <p>If you have discovered an issue on the Stroopwafel grid (such as abuse), please contact <a href=\"https://www.waze.com/forum/ucp.php?i=pm&mode=compose&u=17012866\" target=\"_blank\">GerardterBeke via PM</a>.</p> <h2>Security</h2> <p>If you discover any security related issues, please reach <a href=\"https://www.waze.com/forum/ucp.php?i=pm&mode=compose&u=17969126\" target=\"_blank\">mewsa via PM</a> instead of using the public forum thread. We strive to promptly address security issues.</p></div>";const HTML_MODAL_CHANGELOG = "<div> <h1>Changelog</h1> <div id=\"WME-Stroopwafel-Changelog\"></div></div><style> #WME-Stroopwafel-Changelog div { border-top: 1px solid #bbb; margin-top: 4px; padding-top: 4px; } .Current-Version-Badge { display: inline-block; padding: 4px 8px; border: 1px solid darkred; color: darkred; font-weight: bold; border-radius: 8px; }</style>";const HTML_MODAL_BANNED = "<div id=\"Stroopwafel-Banned-Modal\"> <h1>Everything comes to an end.</h1> <h2>You have been banned from using WME Stroopwafel.</h2> <p>You were banned for: \"<span id=\"Stroopwafel-Ban-Reason\"></span>\". WME Stroopwafel can no longer be used, please uninstall the userscript to continue using Waze Map Editor.</p></div><style> #Stroopwafel-Banned-Modal h1 { font-size: 32px; margin-bottom: 0; } #Stroopwafel-Banned-Modal h2 { font-size: 20px; }</style>";const HTML_MODAL_ADVANCED_SETTINGS = "<div id=\"Advanced-Settings\"> <h1>Advanced Settings</h1> <p>Do not modify these settings if you are not a developer. Wrong settings could break the script.</p> <label for=\"server-url\">Server URL</label> <input type=\"text\" placeholder=\"https://example.com/api\" id=\"server-url\" /> <label for=\"verbose-logs\">Verbose logs</label> <input type=\"checkbox\" id=\"verbose-logs\" /> <button id=\"reset-settings-button\">Reset all settings</button> <button id=\"deactivate-button\">Deactivate (logout)</button> <button id=\"copy-logs-button\">Copy logs</button></div><style> #Advanced-Settings input { display: block; } #Advanced-Settings button { background: #fff; color: #000; border: 2px solid #ff0000; -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; display: block; margin: 10px 5%; width: 90%; text-align: center; } #Advanced-Settings button:hover { background: #bbb; }</style>";const HTML_MODAL_ENTER_KEY = "<div id=\"Stroopwafel-Enter-Key\"> <a href=\"#\" id=\"back-to-activate\">Back</a> <label for=\"Stroopwafel-Key-Input\">Enter your activation key:</label> <input class=\"form-control\" id=\"Stroopwafel-Key-Input\" type=\"password\" placeholder=\"Your activation key\"> <span id=\"checking-key-error\"></span> <button class=\"waze-btn waze-btn-blue\" id=\"btn-enter-key\">Submit</button></div><style> #Stroopwafel-Enter-Key label { display: block; margin-top: 6px; } #Stroopwafel-Enter-Key button { display: block; width: 100%; padding: 6px 0; margin-top: 4px; } #checking-key-error { font-weight: bold; color: darkred; display: none; }</style>";const HTML_MODAL_ACTIVATION = "<div id=\"WME-Activation\"> <div id=\"WME-Activation-Avatar\"></div> <h1>Hi, <span class=\"WME-Activation-Username\"></span>!</h1> <p>Because this script uses shared data, we need to confirm that you are actually <span class=\"WME-Activation-Username\">...</span>. For that reason, an activation key will be sent to your <a href=\"https://www.waze.com/forum/index.php\" target=\"_blank\" title=\"Open Waze forum in a new tab.\">Waze forum</a> account by the name of '<span class=\"WME-Activation-Username\">...</span>'.</p> <div class=\"waze-btn waze-btn-small waze-btn-blue\" id=\"btn-send-key\"> Send Activation Key </div> <span id=\"send-key-success\"> The activation key was sent. Click <a href=\"https://www.waze.com/forum/ucp.php?i=pm&folder=inbox\" target=\"_blank\">here</a> to open your inbox. </span> <span id=\"send-key-error\"></span> <a href=\"#\" id=\"already-have-key\">I already have a key.</a></div><style> #WME-Activation h1 { text-align: center; padding: 10px 0; } #WME-Activation p { display: block; margin: 10px auto; } #WME-Activation .waze-btn { display: block; margin: 5px auto; } #WME-Activation #already-have-key { display: block; margin: 0 auto; text-align: center; } #WME-Activation-Avatar { margin: 15px auto; display: block; width: 150px; height: 150px; border-radius: 50%; background-color: #888888; background-position: center; -webkit-background-size: cover; background-size: cover; } #send-key-error { font-weight: bold; color: darkred; display: none; } #send-key-success { font-weight: bold; color: green; display: none; }</style>";const HTML_MODAL = "<div id=\"WME-Stroopwafel-Modal\"> <div id=\"WME-Stroopwafel-Modal-Content\"></div></div><style> #WME-Stroopwafel-Modal { display: none; position: fixed; z-index: 99999; left: 0; top: 0; width: 100%; height: 100%; overflow: hidden; background-color: rgb(0,0,0); background-color: rgba(0,0,0,0.4); } #WME-Stroopwafel-Modal-Content { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: #fefefe; padding: 20px; border: 1px solid #888; width: 80%; } #WME-Stroopwafel-Modal-Close { display: block; position: absolute; top: 0; right: 0; padding: 8px; cursor: pointer; color: #000; }</style>";const HTML_TAB = "<div id=\"WME-Stroopwafel-Tab\"> <!-- Feedback icon --> <span title=\"Feedback\"> <svg id=\"WME-Stroopwafel-Feedback-Icon\" height=\"20px\" width=\"20px\" viewBox=\"-21 -47 682.66669 682\" xmlns=\"http://www.w3.org/2000/svg\"> <path d=\"m552.011719-1.332031h-464.023438c-48.515625 0-87.988281 39.464843-87.988281 87.988281v283.972656c0 48.414063 39.300781 87.816406 87.675781 87.988282v128.863281l185.191407-128.863281h279.144531c48.515625 0 87.988281-39.472657 87.988281-87.988282v-283.972656c0-48.523438-39.472656-87.988281-87.988281-87.988281zm50.488281 371.960937c0 27.835938-22.648438 50.488282-50.488281 50.488282h-290.910157l-135.925781 94.585937v-94.585937h-37.1875c-27.839843 0-50.488281-22.652344-50.488281-50.488282v-283.972656c0-27.84375 22.648438-50.488281 50.488281-50.488281h464.023438c27.839843 0 50.488281 22.644531 50.488281 50.488281zm0 0\"></path> <path d=\"m171.292969 131.171875h297.414062v37.5h-297.414062zm0 0\"></path> <path d=\"m171.292969 211.171875h297.414062v37.5h-297.414062zm0 0\"></path> <path d=\"m171.292969 291.171875h297.414062v37.5h-297.414062zm0 0\"></path> </svg> </span> <!-- Stroopwafel logo --> <img width=\"50\" height=\"50\" id=\"WME-Stroopwafel-Logo\" src=\"data:image/png;base64,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\" alt=\"Stroopwafel\"> <h2 id=\"WME-Stroopwafel-Title\">WME Stroopwafel</h2> <!-- Activation section --> <div id=\"WME-Stroopwafel-Activate-Section\" data-stroopwafel-show=\"guest\"> <p>Your copy of WME Stroopwafel is currently not activated.</p> <div class=\"waze-btn waze-btn-small waze-btn-white\" id=\"btn-open-activate-modal\"> Activate </div> </div> <!-- Aspects section --> <div id=\"WME-Stroopwafel-Aspect-Section\" class=\"WME-Stroopwafel-Tab-Section\" data-stroopwafel-show=\"activated\"> <p>Selected aspects</p> <div id=\"WME-Stroopwafel-Aspect-Checkboxes\"></div> </div> <!-- User section --> <div id=\"WME-Stroopwafel-User-Section\" class=\"WME-Stroopwafel-Tab-Section\" data-stroopwafel-show=\"activated\"> <p>Currently activated as:</p> <span id=\"WME-Stroopwafel-User-Section-Name\"></span> (level <span id=\"WME-Stroopwafel-User-Section-Level\"></span>) </div> <!-- Changelog --> <a class=\"waze-btn waze-btn-smaller waze-btn-white\" href=\"#\" id=\"WME-Stroopwafel-Changelog-Btn\">Changelog</a> <!-- Advanced settings --> <a href=\"#\" id=\"btn-open-advanced-settings\">Advanced Settings</a></div><style> #WME-Stroopwafel-Tab { position: relative; } *[data-stroopwafel-show] { display: none; } #WME-Stroopwafel-Feedback-Icon { position: absolute; top: 0; right: 0; fill: #bbb; } #WME-Stroopwafel-Feedback-Icon:hover { cursor: pointer; fill: #000; } #WME-Stroopwafel-Logo { margin: 5px auto; display: block; } #WME-Stroopwafel-Logo:hover { animation: rotation 3s infinite linear; } @keyframes rotation { 50% { transform: rotate(360deg); } 100% { transform: rotate(0deg); } } #WME-Stroopwafel-Title { text-align: center; } #WME-Stroopwafel-Activate-Section { margin-bottom: 10px; } .WME-Stroopwafel-Tab-Section { margin-bottom: 10px; border: 1px solid #000; border-radius: 5px; padding: 10px; background: #fff; } #WME-Stroopwafel-User-Section-Name { display: block; margin-top: 4px; font-weight: bold; } #WME-Stroopwafel-User-Section-Level { display: inline-block; font-weight: bold; } #WME-Stroopwafel-Aspect-Section input[type=checkbox] { display: inline-block; } #WME-Stroopwafel-Aspect-Section label { margin-left: 4px; } #WME-Stroopwafel-Aspect-Section div { display: block; } #WME-Stroopwafel-Aspect-Section div + div { margin-top: 2px; } #WME-Stroopwafel-Changelog-Btn { display: block; padding: 0 10px; } #btn-open-advanced-settings { font-size: 10px; display: inline-block; margin-top: 4px; color: #bbb; }</style>";!function(t,n){"function"==typeof define&&define.amd?define(["b"],function(e){return t.returnExportsGlobal=n()}):"object"==typeof module&&module.exports?module.exports=n(require("b")):t.OpenLocationCode=n()}(this,function(){var r={CODE_PRECISION_NORMAL:10,CODE_PRECISION_EXTRA:11},f="23456789CFGHJMPQRVWX",y=f.length,M=Math.pow(y,4),m=Math.pow(y,3),s=[20,1,.05,.0025,125e-6],w=Math.pow(5,4),v=Math.pow(4,4),C=m*Math.pow(5,5),b=m*Math.pow(4,5);r.getAlphabet=function(){return f};var t=r.isValid=function(e){if(!e||"string"!=typeof e)return!1;if(-1==e.indexOf("+"))return!1;if(e.indexOf("+")!=e.lastIndexOf("+"))return!1;if(1==e.length)return!1;if(8<e.indexOf("+")||e.indexOf("+")%2==1)return!1;if(-1<e.indexOf("0")){if(e.indexOf("+")<8)return!1;if(0==e.indexOf("0"))return!1;var t=e.match(new RegExp("(0+)","g"));if(1<t.length||t[0].length%2==1||6<t[0].length)return!1;if("+"!=e.charAt(e.length-1))return!1}if(e.length-e.indexOf("+")-1==1)return!1;for(var n=0,o=(e=e.replace(new RegExp("\\++"),"").replace(new RegExp("0+"),"")).length;n<o;n++){var a=e.charAt(n).toUpperCase();if("+"!=a&&-1==f.indexOf(a))return!1}return!0},l=r.isShort=function(e){return!!t(e)&&0<=e.indexOf("+")&&e.indexOf("+")<8},S=r.isFull=function(e){return!!t(e)&&(!l(e)&&(!(180<=f.indexOf(e.charAt(0).toUpperCase())*y)&&!(1<e.length&&360<=f.indexOf(e.charAt(1).toUpperCase())*y)))},d=r.encode=function(e,t,n){if(e=Number(e),t=Number(t),n=void 0===n?r.CODE_PRECISION_NORMAL:Math.min(15,Number(n)),isNaN(e)||isNaN(t)||isNaN(n))throw new Error("ValueError: Parameters are not numbers");if(n<2||n<10&&n%2==1)throw new Error("IllegalArgumentException: Invalid Open Location Code length");e=u(e),t=p(t),90==e&&(e-=h(n));var o="",a=Math.floor(Math.round((e+90)*C*1e6)/1e6),i=Math.floor(Math.round((t+180)*b*1e6)/1e6);if(10<n)for(var s=0;s<5;s++)o=f.charAt(a%5*4+i%4)+o,a=Math.floor(a/5),i=Math.floor(i/4);else a=Math.floor(a/Math.pow(5,5)),i=Math.floor(i/Math.pow(4,5));for(s=0;s<5;s++)o=f.charAt(i%y)+o,o=f.charAt(a%y)+o,a=Math.floor(a/y),i=Math.floor(i/y);return o=o.substring(0,8)+"+"+o.substring(8),8<=n?o.substring(0,n+1):o.substring(0,n)+Array(8-n+1).join("0")+"+"},c=r.decode=function(e){if(!S(e))throw new Error("IllegalArgumentException: Passed Open Location Code is not a valid full code: "+e);e=e.replace("+","").replace(/0/g,"").toLocaleUpperCase("en-US");for(var t=-90*m,n=-180*m,o=0,a=0,i=Math.min(e.length,10),s=M,r=0;r<i;r+=2)t+=f.indexOf(e.charAt(r))*s,n+=f.indexOf(e.charAt(r+1))*s,r<i-2&&(s/=y);var l=s/m,d=s/m;if(10<e.length){for(var c=w,u=v,i=Math.min(e.length,15),r=10;r<i;r++){var h=f.indexOf(e.charAt(r));o+=Math.floor(h/4)*c,a+=h%4*u,r<i-1&&(c/=5,u/=4)}l=c/C,d=u/b}var p=t/m+o/C,g=n/m+a/b;return new _(Math.round(1e14*p)/1e14,Math.round(1e14*g)/1e14,Math.round(1e14*(p+l))/1e14,Math.round(1e14*(g+d))/1e14,Math.min(e.length,15))};r.recoverNearest=function(e,t,n){if(!l(e)){if(S(e))return e.toUpperCase();throw new Error("ValueError: Passed short code is not valid: "+e)}if(t=Number(t),n=Number(n),isNaN(t)||isNaN(n))throw new Error("ValueError: Reference position are not numbers");t=u(t),n=p(n);var o=8-(e=e.toUpperCase()).indexOf("+"),a=Math.pow(20,2-o/2),i=a/2,e=c(d(t,n).substr(0,o)+e);return t+i<e.latitudeCenter&&-90<=e.latitudeCenter-a?e.latitudeCenter-=a:t-i>e.latitudeCenter&&e.latitudeCenter+a<=90&&(e.latitudeCenter+=a),n+i<e.longitudeCenter?e.longitudeCenter-=a:n-i>e.longitudeCenter&&(e.longitudeCenter+=a),d(e.latitudeCenter,e.longitudeCenter,e.codeLength)},r.shorten=function(e,t,n){if(!S(e))throw new Error("ValueError: Passed code is not valid and full: "+e);if(-1!=e.indexOf("0"))throw new Error("ValueError: Cannot shorten padded codes: "+e);e=e.toUpperCase();var o=c(e);if(o.codeLength<6)throw new Error("ValueError: Code length must be at least 6");if(t=Number(t),n=Number(n),isNaN(t)||isNaN(n))throw new Error("ValueError: Reference position are not numbers");t=u(t),n=p(n);for(var a=Math.max(Math.abs(o.latitudeCenter-t),Math.abs(o.longitudeCenter-n)),i=s.length-2;1<=i;i--)if(a<.3*s[i])return e.substring(2*(i+1));return e};var u=function(e){return Math.min(90,Math.max(-90,e))},h=function(e){return e<=10?Math.pow(y,Math.floor(e/-2+2)):Math.pow(y,-3)/Math.pow(5,e-10)},p=function(e){for(;e<-180;)e+=360;for(;180<=e;)e-=360;return e},_=r.CodeArea=function(e,t,n,o,a){return new r.CodeArea.fn.Init(e,t,n,o,a)};return _.fn=_.prototype={Init:function(e,t,n,o,a){this.latitudeLo=e,this.longitudeLo=t,this.latitudeHi=n,this.longitudeHi=o,this.codeLength=a,this.latitudeCenter=Math.min(e+(n-e)/2,90),this.longitudeCenter=Math.min(t+(o-t)/2,180)}},_.fn.Init.prototype=_.fn,r});let Changelog={1.8:{releasedAt:"December 8, 2021 19:32",changes:["You can now update up to 100 tiles at once."]},1.7:{releasedAt:"September 17, 2021 19:15",changes:['Added "Junction Box Roundabouts" aspect.','Added "Road Widths" aspect.',"Added keybind to toggle grid (CTRL + /)."]},1.6:{releasedAt:"May 24, 2021 14:40",changes:['Added "Road Shields" aspect.','Added "Exit Signs" aspect.',"Added support for longer aspect names.","Added a feedback button to the sidebar."]},1.5:{releasedAt:"May 18, 2021 16:30",changes:["First release ready for public use."]},"1.0":{releasedAt:"April 25, 2021 20:00",changes:["First beta release."]}},Modal_Activation=function(){return{sendingKey:!1,sendKeyRequest:null,init:function(e){$(e).find(".WME-Activation-Username").text(W.loginManager.user.userName),$(e).find("#WME-Activation-Avatar").css("background-image",'url("'+W.loginManager.user.profileImageUrl+'")'),$(e).find("#btn-send-key").click(this.sendKey.bind(this)),$(e).find("#already-have-key").click(()=>{Modal.show(ModalType.EnterKey)})},onClose:function(){null!==this.sendKeyRequest&&(log("Activation key request was aborted (modal closed)."),this.sendKeyRequest.abort())},sendKey:function(){var e;this.sendingKey||(this.sendingKey=!0,$("#btn-send-key").addClass("disabled"),$("#send-key-error").hide(),e=()=>{this.sendingKey=!1,$("#btn-send-key").removeClass("disabled")},log("Requesting activation key..."),this.sendKeyRequest=$.post(settings.serverURL+"/request-activation-key",{username:W.loginManager.user.userName}).done(e=>{switch(log("Activation key request responded with:"),log(e),e.status){case"success":$("#btn-send-key").hide(),$("#send-key-success").show();break;case"error":this.showSendKeyError(e.error)}}).fail(()=>{log("Could not make POST request to server."),this.showSendKeyError("Connection to Stroopwafel server could not be established.")}).always(()=>{this.sendKeyRequest=null,e()}))},showSendKeyError:function(e){let t=$("#send-key-error");t.text(e),t.show()}}},Modal_Advanced_Settings=function(){return{init:function(e){$(e).find("#server-url").val(settings.serverURL),$(e).find("#verbose-logs").prop("checked",settings.verboseLogs),$(e).find("#verbose-logs").change(this.updateVerboseLogs),$(e).find("#reset-settings-button").click(this.resetSettings),$(e).find("#deactivate-button").click(this.deactivate),$(e).find("#server-url").change(this.updateServerURL),$(e).find("#copy-logs-button").click(this.copyLogs)},resetSettings:function(){localStorage.removeItem(LOCALSTORAGE_KEY_SETTINGS),location.reload()},deactivate:function(){settings.activationKey=null,saveSettings(),User.updateUser(null),$("#deactivate-button").text("Deactivated")},updateServerURL:function(){var e=$("#server-url").val();settings.serverURL=e,saveSettings(),log("User updated server URL to "+e)},updateVerboseLogs:function(){settings.verboseLogs=this.checked,saveSettings(),settings.verboseLogs?Toast.show("Verbose logs enabled."):Toast.show("Verbose logs disabled.")},copyLogs:function(){Logger.copyLogsToClipboard(),$("#copy-logs-button").text("Copied"),Toast.show("Logs have been copied to the clipboard.")}}},Modal_Banned=function(){return{init:function(e){$(e).find("#Stroopwafel-Ban-Reason").text(User.current.ban.reason)}}},Modal_Changelog=function(){return{init:function(e){var n=GM_info.script.version;for(const o in Changelog){let e=$("<div></div>");e.append("<h4>v"+o+"</h4>"),n===o&&e.append('<span class="Current-Version-Badge">current version</span>'),e.append("<p>released "+Changelog[o].releasedAt+"</p>");let t=$("<ul></ul>");Changelog[o].changes.forEach(e=>{t.append("<li>"+e+"</li>")}),e.append(t),$("#WME-Stroopwafel-Changelog").append(e)}}}},Modal_Enter_Key=function(){return{submittingKey:!1,init:function(e){$(e).find("#back-to-activate").click(()=>{Modal.show(ModalType.Activate)}),$(e).find("#btn-enter-key").click(this.submitKey.bind(this))},submitKey:function(){var e,t;this.submittingKey||(this.submittingKey=!0,$("#btn-enter-key").addClass("disabled"),$("#checking-key-error").hide(),e=()=>{this.submittingKey=!1,$("#btn-enter-key").removeClass("disabled")},log("Checking entered activation key "+(t=$("#Stroopwafel-Key-Input").val())+"..."),$.post(settings.serverURL+"/check-activation-key",{activationKey:t,username:W.loginManager.user.userName}).done(e=>{log("Activation key was valid! Request responded with:"),log(e),settings.activationKey=t,saveSettings(),Modal.close(),Toast.show("Activation successful!","success"),User.updateUser(e.user)}).fail(()=>{log("Checking activation key has failed!"),this.showCheckingKeyError("Activation failed.")}).always(()=>{e()}))},showCheckingKeyError:function(e){let t=$("#checking-key-error");t.text(e),t.show()}}};function distanceInKM(t,n){if(t.lat===n.lat&&t.lon===n.lat)return 0;{var o=Math.PI*t.lat/180,a=Math.PI*n.lat/180,n=t.lon-n.lon,n=Math.PI*n/180;let e=Math.sin(o)*Math.sin(a)+Math.cos(o)*Math.cos(a)*Math.cos(n);return 1<e&&(e=1),e=Math.acos(e),e=180*e/Math.PI,e=60*e*1.1515,e*=1.609344,e}}function log(){var t=arguments;for(let e=0;e<t.length;e++)Logger.log(t[e])}let Logger={maxLogs:1e3,logs:[],log:function(e){settings.verboseLogs&&console.log(e);let t=new Date;let n="["+(t.getDate()+"/"+(t.getMonth()+1)+"/"+t.getFullYear()+" @ "+t.getHours()+":"+t.getMinutes()+":"+t.getSeconds())+"] ";if("string"==typeof e)n+=e;else try{n+=JSON.stringify(e)}catch(e){n+="Logger could not stringify this object!"}Logger.logs.push(n),Logger.clearOldLogs()},clearOldLogs:function(){Logger.logs.length>Logger.maxLogs&&Logger.logs.shift()},copyLogsToClipboard:function(){const e=document.createElement("textarea");e.value=Logger.logs.join("\n"),document.body.appendChild(e),e.select(),document.execCommand("copy"),document.body.removeChild(e)}},LOCALSTORAGE_KEY_SETTINGS="WMEMarkerSettings",RETRY_INIT_AFTER=1e3,RETRY_INIT_LIMIT=10,WAZE_MAP=null,settings={displayPlusCodesGridLayer:!1,serverURL:"//wme-stroopwafel-server.herokuapp.com/api",activationKey:null,verboseLogs:!1},pluscodesLayer;function init(e=1){if(!(e>RETRY_INIT_LIMIT)){function t(){setTimeout(init,RETRY_INIT_AFTER,e+1)}return(log("Initializing (attempt "+e+"/"+RETRY_INIT_LIMIT+")"),void 0===W.map)?(log("Waze map has not loaded yet."),void t()):"undefined"==typeof $?(log("jQuery has not loaded yet."),void t()):"undefined"==typeof WazeWrap||void 0===WazeWrap.Interface?(log("WazeWrap has not loaded yet."),void t()):(WAZE_MAP=W.map.getOLMap(),loadSettings(),WazeWrap.Interface.AddLayerCheckbox("Display","Pluscodes Grid",settings.displayPlusCodesGridLayer,plusCodesGridLayerToggled),pluscodesLayer=new OpenLayers.Layer.Vector("WME Marker",{uniqueName:"__WME_Marker",visibility:!0}),WAZE_MAP.addLayer(pluscodesLayer),log("Pluscodes layer has been added."),WAZE_MAP.events.register("moveend",null,function(){GridData.checkForUpdates(),Grid.draw()}),GridSquareTooltip.init(),Modal.init(),Grid.init(),GridData.init(),ContextMenu.init(),Tab.init(),Toast.init(),User.init(),void document.addEventListener("keydown",e=>{"/"===e.key&&e.ctrlKey&&(settings.displayPlusCodesGridLayer?Toast.show("Hiding pluscodes layer."):Toast.show("Showing pluscodes layer."),plusCodesGridLayerToggled(!settings.displayPlusCodesGridLayer),e.preventDefault())}))}log("Script could not initialize. (too many attempts)")}function plusCodesGridLayerToggled(e){pluscodesLayer.setVisibility(e),settings.displayPlusCodesGridLayer=e,saveSettings(),e?(Grid.draw(),GridData.checkForUpdates()):(e=new Event("stroopwafel:pluscodes-layer-disabled"),document.dispatchEvent(e))}function loadSettings(){var e=localStorage.getItem(LOCALSTORAGE_KEY_SETTINGS);null==e?log("No settings found. Using default settings:",settings):(settings=JSON.parse(e),log("Settings loaded from localStorage:",settings))}function saveSettings(){localStorage.setItem(LOCALSTORAGE_KEY_SETTINGS,JSON.stringify(settings)),log("Settings saved:",settings)}init();let GridSquareTooltip={timeout:null,lastCoordinates:null,lastClientMousePosition:null,currentPluscode:null,init:function(){log("Initializing grid square tooltip.");let e=$("#map");e.append(HTML_GRID_SQUARE_TOOLTIP),WAZE_MAP.events.register("mousemove",WAZE_MAP,this.onMouseMove.bind(this)),e.on("mouseleave",this.forceHideTooltip.bind(this)),WAZE_MAP.events.register("movestart",WAZE_MAP,this.forceHideTooltip.bind(this)),WAZE_MAP.events.register("zoomstart",WAZE_MAP,this.forceHideTooltip.bind(this)),document.addEventListener("stroopwafel:pluscodes-layer-disabled",this.forceHideTooltip.bind(this))},onMouseMove:function(e){var t;settings.displayPlusCodesGridLayer&&(Grid.selectControlActivated||W.map.zoom<2||(t=WAZE_MAP.getLonLatFromPixel(WAZE_MAP.events.getMousePosition(e)),t=OpenLayers.Projection.transform({x:t.lon,y:t.lat},"EPSG:3857","EPSG:4326"),this.lastCoordinates={lat:t.y,lon:t.x},this.lastClientMousePosition={x:e.offsetX,y:e.offsetY},clearTimeout(this.timeout),this.timeout=setTimeout(this.showTooltip.bind(this),500)))},showTooltip:function(){var t=OpenLocationCode.encode(this.lastCoordinates.lat,this.lastCoordinates.lon,Grid.getPrecision());if(t!==this.currentPluscode){var o=GridData.data.find(e=>e.plus_code===t);this.currentPluscode=t;let e=$("#WME-Stroopwafel-GridSquare-Tooltip");e.find("#Current-Grid-Square-Code").text(t);let n=$("#Current-Grid-Square-Aspect-Information");if(n.empty(),void 0!==o&&o.has_nothing){let e=$("<tr></tr>");e.text("️Marked as empty"),n.append(e)}else ContextMenu.getShownAspects().forEach(e=>{let t=$("<tr></tr>");void 0!==o&&o[e.name]?t.text("✅ "+e.displayName):t.text("❌ "+e.displayName),n.append(t)});var a=e.width(),i=e.height();e.css("top",this.lastClientMousePosition.y-50-i+"px"),e.css("left",this.lastClientMousePosition.x-a/2+"px"),e.show()}},hideTooltip:function(){null!==this.currentPluscode&&(this.currentPluscode=null,$("#WME-Stroopwafel-GridSquare-Tooltip").hide())},forceHideTooltip:function(){clearTimeout(this.timeout),this.hideTooltip()},onStartGridSelect:function(){this.forceHideTooltip()}},User={current:null,activated:!1,init:function(){null!==settings.activationKey?this.checkKey():this.updateUser(null)},checkKey:function(){log("Checking the saved activation key "+settings.activationKey+"..."),$.post(settings.serverURL+"/check-activation-key",{activationKey:settings.activationKey,username:W.loginManager.user.userName}).done(e=>{log("Activation key is still valid! Request responded with:"),log(e),this.updateUser(e.user)}).fail(()=>{log('Checking activation key has failed! Removing the "useless" key.'),settings.activationKey=null,saveSettings(),this.updateUser(null)})},updateUser:function(e){this.current=e,this.activated=null!==e,null!==this.current&&this.current.ban.banned&&Modal.show(ModalType.Banned);e=new Event("stroopwafel:user-changed");document.dispatchEvent(e)}},GridData={data:[],updating:!1,lastUpdate:null,init:function(){GridData.checkForUpdates(),$(".reload-button-region").click(()=>{GridData.checkForUpdates(!0)})},checkForUpdates:function(t=!1){var n=OpenLayers.Projection.transform({x:WAZE_MAP.center.lon,y:WAZE_MAP.center.lat},"EPSG:3857","EPSG:4326");if(log("Checking for data updates at lat "+(n={lat:n.y,lon:n.x}).lat+", lon "+n.lon+"."),GridData.updating)log("Data update deferred. Already updating!");else if(settings.displayPlusCodesGridLayer){if(t)log("Starting data update! Update was forced.");else if(null!==GridData.lastUpdate){if(null===GridData.lastUpdate.distance)return void log("Data update deferred. No distance is known in memory.");let e=distanceInKM(n,GridData.lastUpdate.position);t=.9*GridData.lastUpdate.distance;if(e<t)return void log("Data update deferred. Only "+e.toFixed(2)+"km was travelled. ("+t+"km required)");log("Starting data update! Distance requirement met: "+e.toFixed(2)+"km of the required "+t+"km")}else log("Starting data update! Data was not updated before.");GridData.update(n)}else log("Data update deferred. Pluscodes layer is hidden.")},update:function(e){GridData.updating=!0,GridData.lastUpdate={position:e,distance:null,time:Date.now()},$.get(settings.serverURL+"/grid",{fromLat:e.lat,fromLon:e.lon}).done(function(e){log("Data received from server: "+e.grid.length+" data tiles in a range of "+e.distance+"km"),GridData.data=e.grid,GridData.lastUpdate.distance=e.distance,GridData.updating=!1,Grid.draw()})}},gridStyle={default:{border:"#000000",borderWidth:1,borderOpacity:.3,fill:"#b0b0b0",fillOpacity:.3},unfinished:{border:"#b08720",borderWidth:2,borderOpacity:1,fill:"#ffc430",fillOpacity:.3},finished:{border:"#02a80d",borderWidth:2,borderOpacity:1,fill:"#00ff11",fillOpacity:.3},empty:{border:"#fff",borderWidth:0,borderOpacity:0,fill:"rgba(0, 0, 0, 0)",fillOpacity:.3},highlight:{fill:"#51dcea"}},Grid={grid:[],selectControl:null,clickControl:null,selectControlActivated:!1,init:function(){log("Initializing grid."),Grid.registerEvents(),Grid.draw()},registerEvents:function(){this.selectControl=new OpenLayers.Control.SelectFeature(pluscodesLayer,{hover:!1,highlightOnly:!1,box:!0,multiple:!0,eventListeners:{beforefeaturehighlighted:function(e){e.feature.style.fillColor=gridStyle.highlight.fill},featureunhighlighted:function(e){var t=Grid.getStyleForPluscode(e.feature.attributes.plusCode);e.feature.style.fillColor=t.fill}},onSelect:function(e){ContextMenu.updateSelection(e.layer.selectedFeatures)}});let e=OpenLayers.Class(OpenLayers.Control,{defaultHandlerOptions:{single:!0,double:!1,pixelTolerance:0,stopSingle:!1,stopDouble:!1},initialize:function(e){this.handlerOptions=OpenLayers.Util.extend({},this.defaultHandlerOptions),OpenLayers.Control.prototype.initialize.apply(this,arguments),this.handler=new OpenLayers.Handler.Click(this,{click:this.trigger},this.handlerOptions)},trigger:this.onClickToSelect.bind(this)});this.clickControl=new e,W.map.addControl(this.clickControl),W.map.addControl(this.selectControl),document.addEventListener("keydown",Grid.activateSelect),document.addEventListener("keyup",Grid.deactivateSelect)},draw:function(){var t,e,n;settings.displayPlusCodesGridLayer&&(pluscodesLayer.removeAllFeatures(),Grid.grid=[],t=Grid.getPrecision(),e={lat:(e=OpenLayers.Projection.transform({x:WAZE_MAP.center.lon,y:WAZE_MAP.center.lat},"EPSG:3857","EPSG:4326")).y,lon:e.x},n=OpenLocationCode.encode(e.lat,e.lon,t),e={lat:(n=OpenLocationCode.decode(n)).latitudeCenter,lon:n.longitudeCenter},Grid.drawGridInDirection(e,{lat:1,lon:0},t,e=>{Grid.drawGridInDirection(e,{lat:0,lon:1},t),Grid.drawGridInDirection(e,{lat:0,lon:-1},t)}),Grid.drawGridInDirection(e,{lat:-1,lon:0},t,e=>{Grid.drawGridInDirection(e,{lat:0,lon:1},t),Grid.drawGridInDirection(e,{lat:0,lon:-1},t)}))},drawGridInDirection:function(e,t,n,o=null){let a={lat:e.lat,lon:e.lon};for(;Grid.shouldDrawAt(a,n);){var i=OpenLocationCode.encode(a.lat,a.lon,n),s=Grid.drawGridSquare(i);Grid.grid.push({code:i,feature:s.feature}),null!==o&&o(a),a.lat+=t.lat*s.dimensions.lat,a.lon+=t.lon*s.dimensions.lon}},drawGridSquare:function(t){var e=OpenLocationCode.decode(t),n=new OpenLayers.Geometry.LinearRing([new OpenLayers.Geometry.Point(e.longitudeLo,e.latitudeLo),new OpenLayers.Geometry.Point(e.longitudeHi,e.latitudeLo),new OpenLayers.Geometry.Point(e.longitudeHi,e.latitudeHi),new OpenLayers.Geometry.Point(e.longitudeLo,e.latitudeHi)]).transform(new OpenLayers.Projection("EPSG:4326"),WAZE_MAP.getProjection()),o=Grid.getStyleForPluscode(t);let a=null;if(!Grid.hasDrawnCode(t)){let e=!0;W.map.zoom<=1&&(e=!1),a=new OpenLayers.Feature.Vector(n,{plusCode:t},{stroke:e,strokeColor:o.border,strokeOpacity:o.borderOpacity,strokeWidth:o.borderWidth,fill:!0,fillColor:o.fill,fillOpacity:o.fillOpacity}),pluscodesLayer.addFeatures([a])}return{dimensions:{lon:e.longitudeHi-e.longitudeLo,lat:e.latitudeHi-e.latitudeLo},feature:a}},shouldDrawAt:function(e,t){let n=W.map.getExtent();e=OpenLocationCode.encode(e.lat,e.lon,t),t=OpenLocationCode.decode(e),e=OpenLayers.Projection.transform({x:t.longitudeLo,y:t.latitudeLo},"EPSG:4326","EPSG:3857"),t=OpenLayers.Projection.transform({x:t.longitudeHi,y:t.latitudeHi},"EPSG:4326","EPSG:3857"),e=new OpenLayers.Bounds(e.x,t.y,t.x,e.y);return n.intersectsBounds(e)},activateSelect:function(e){settings.displayPlusCodesGridLayer&&(Grid.selectControlActivated||W.map.zoom<=1||"Meta"!==e.key&&"Control"!==e.key||($("#topbar-container").append('<span id="selectNotification" style="display:block;text-align:center;color:white;text-shadow: 0px 0px 4px #000;font-weight:bold;">Drag or click to make your selection.</span>'),Grid.selectControl.activate(),Grid.clickControl.activate(),Grid.selectControlActivated=!0,GridSquareTooltip.onStartGridSelect()))},deactivateSelect:function(e){Grid.selectControlActivated&&("Meta"!==e.key&&"Control"!==e.key||($("#selectNotification").remove(),Grid.selectControl.deactivate(),Grid.clickControl.deactivate(),Grid.selectControlActivated=!1))},getPrecision:function(){return 8},hasDrawnCode:function(t){return void 0!==Grid.grid.find(e=>e.code===t)},getStyleForPluscode:function(t){var n=GridData.data.find(e=>e.plus_code===t);if(void 0===n)return gridStyle.default;if(n.has_nothing)return gridStyle.empty;let e=ContextMenu.getShownAspects();if(e.length<1)return gridStyle.default;let o=0;return e.forEach(e=>{n[e.name]&&o++}),o===e.length?gridStyle.finished:0===o?gridStyle.default:gridStyle.unfinished},onClickToSelect:function(e){e=WAZE_MAP.getLonLatFromPixel(e.xy);let n=new OpenLayers.Geometry.Point(e.lon,e.lat);pluscodesLayer.features.forEach(e=>{var t;n.intersects(e.geometry)&&(pluscodesLayer.selectedFeatures.includes(e)?(-1<(t=pluscodesLayer.selectedFeatures.indexOf(e))&&pluscodesLayer.selectedFeatures.splice(t,1),ContextMenu.updateSelection(pluscodesLayer.selectedFeatures),t=this.getStyleForPluscode(e.attributes.plusCode),e.style.fillColor=t.fill):(pluscodesLayer.selectedFeatures.push(e),ContextMenu.updateSelection(pluscodesLayer.selectedFeatures),e.style.fillColor=gridStyle.highlight.fill),pluscodesLayer.redraw())})}},Tab={init:function(){log("Initializing tab."),new WazeWrap.Interface.Tab("Stroopwafel",HTML_TAB,Tab.initTab.bind(this)),document.addEventListener("stroopwafel:user-changed",this.onUserChanged.bind(this))},initTab:function(){$("#WME-Stroopwafel-Feedback-Icon").click(function(){Modal.show(ModalType.Feedback)}),$("#btn-open-activate-modal").click(function(){Modal.show(ModalType.Activate)}),$("#WME-Stroopwafel-Changelog-Btn").click(function(){Modal.show(ModalType.Changelog)}),$("#btn-open-advanced-settings").click(function(){Modal.show(ModalType.AdvancedSettings)}),this.createAspectCheckboxes()},onUserChanged:function(){null!==User.current?($("#WME-Stroopwafel-User-Section-Name").text(User.current.username),$("#WME-Stroopwafel-User-Section-Level").text(User.current.editor_level),$('[data-stroopwafel-show="guest"]').hide(),$('[data-stroopwafel-show="activated"]').show()):($('[data-stroopwafel-show="activated"]').hide(),$('[data-stroopwafel-show="guest"]').show())},createAspectCheckboxes:function(){let o=$("#WME-Stroopwafel-Aspect-Checkboxes");ContextMenu.aspects.forEach(e=>{let t=$("<div></div>"),n=$('<input type="checkbox" id="WME-Stroopwafel-Checkbox-'+e.name+'">');e.shown&&n.prop("checked",!0),t.append(n),t.append($('<label for="WME-Stroopwafel-Checkbox-'+e.name+'">'+e.displayName+"</label>")),o.append(t),n.change(()=>{this.onAspectCheckboxValueChanged(e.name)})})},onAspectCheckboxValueChanged:function(t){let e=ContextMenu.aspects.find(e=>e.name===t);e.shown=$("#WME-Stroopwafel-Checkbox-"+e.name).is(":checked"),ContextMenu.updateAspectsHTML(),Grid.draw()}},Modal={shown:!1,animationSpeed:400,currentModalJS:null,init:function(){log("Initializing modal."),$("body").append(HTML_MODAL)},show:function(e){let t=$("#WME-Stroopwafel-Modal"),n=$("#WME-Stroopwafel-Modal-Content");if(n.html(e.html),e.showCloseButton){let e=$('<span id="WME-Stroopwafel-Modal-Close">✕</span>');e.click(this.close),n.append(e)}switch(null!==e.js&&(Modal.currentModalJS=e.js()),Modal.callOptionalModalFunction("init",n),e.modalSize){case"tight":n.css("width","300px");break;case"large":n.css("width","600px")}Modal.shown||(t.fadeIn(Modal.animationSpeed),Modal.shown=!0)},close:function(){if(Modal.shown){Modal.callOptionalModalFunction("onClose");let e=$("#WME-Stroopwafel-Modal");e.fadeOut(Modal.animationSpeed),Modal.shown=!1,Modal.currentModalJS=null}},callOptionalModalFunction:function(e,...t){if(null!==Modal.currentModalJS&&"function"==typeof Modal.currentModalJS[e])return Modal.currentModalJS[e].apply(Modal.currentModalJS,t)}},ModalType={Activate:{html:HTML_MODAL_ACTIVATION,js:Modal_Activation,modalSize:"tight",showCloseButton:!0},EnterKey:{html:HTML_MODAL_ENTER_KEY,js:Modal_Enter_Key,modalSize:"tight",showCloseButton:!1},AdvancedSettings:{html:HTML_MODAL_ADVANCED_SETTINGS,js:Modal_Advanced_Settings,modalSize:"tight",showCloseButton:!0},Changelog:{html:HTML_MODAL_CHANGELOG,js:Modal_Changelog,modalSize:"large",showCloseButton:!0},Banned:{html:HTML_MODAL_BANNED,js:Modal_Banned,modalSize:"large",showCloseButton:!1},Feedback:{html:HTML_MODAL_FEEDBACK,js:null,modalSize:"large",showCloseButton:!0}},ContextMenu={shown:!1,saving:!1,selection:[],aspects:[{displayName:"Empty",name:"has_nothing",shown:!1,status:"-"},{displayName:"Aligned satellite images",name:"has_aligned_satellite_images",shown:!1,status:"-"},{displayName:"Roads",name:"has_roads",shown:!1,status:"-"},{displayName:"Street names",name:"has_street_names",shown:!1,status:"-"},{displayName:"City names",name:"has_city_names",shown:!1,status:"-"},{displayName:"House Numbers",name:"has_house_numbers",shown:!1,status:"-"},{displayName:"Speed limits",name:"has_speed_limits",shown:!1,status:"-"},{displayName:"Places",name:"has_places",shown:!1,status:"-"},{displayName:"Lane Guidance",name:"has_lane_guidance",shown:!1,status:"-"},{displayName:"Nature",name:"has_nature",shown:!1,status:"-"},{displayName:"Speed Camera's and RRC's",name:"has_speed_cameras_and_rrc",shown:!1,status:"-"},{displayName:"Road shields",name:"has_road_shields",shown:!1,status:"-"},{displayName:"Exit signs",name:"has_exit_signs",shown:!1,status:"-"},{displayName:"Junction boxes",name:"has_junction_boxes",shown:!1,status:"-"},{displayName:"WME Toolbox checks",name:"has_toolbox_checks",shown:!1,status:"-"},{displayName:"Road Widths",name:"has_road_widths",shown:!1,status:"-"},{displayName:"Junction Box Roundabouts",name:"has_junction_box_roundabouts",shown:!1,status:"-"}],init:function(){log("Initializing context menu."),$("body").append(HTML_CONTEXT_MENU),$("#editor-container").contextmenu(this.activate.bind(this)),$(document).click(this.clickOutside.bind(this)),$("#WME_Marker_Context_Save_Btn").click(this.onClickSave.bind(this)),$("#WME-Stroopwafel-Context-Close").click(this.deactivate.bind(this)),this.addAspectsHTML(),this.updateAspectsHTML(),this.updateSelection([])},activate:function(e){pluscodesLayer.selectedFeatures.length<1||($("#WME_Marker_Context_Menu").show(),this.shown=!0,this.setPosition(e),e.preventDefault())},deactivate:function(){$("#WME_Marker_Context_Menu").hide(),this.shown=!1},clickOutside:function(t){if(this.shown&&!this.saving){let e=$(t.target);e.closest("#WME_Marker_Context_Menu").length||this.deactivate()}},setPosition:function(e){let t=$("#WME_Marker_Context_Menu"),n={};var o={x:e.pageX,y:e.pageY},e={x:t.outerWidth(),y:t.outerHeight()};o.x+e.x>$(window).width()+$(window).scrollLeft()?n.x=o.x-e.x:n.x=o.x,o.y+e.y>$(window).height()+$(window).scrollTop()?n.y=o.y-e.y:n.y=o.y,t.css("left",n.x+"px"),t.css("top",n.y+"px")},updateSelection:function(e){$("#WME_Marker_Context_Menu #selectionCount").text(e.length),this.selection=e;let t=$("#WME_Marker_Context_Save_Btn");this.selection.length<1?(t.removeClass("waze-btn-green"),t.addClass("waze-btn-disabled")):(t.addClass("waze-btn-green"),t.removeClass("waze-btn-disabled"))},onClickSave:function(){if(!(this.saving||this.selection.length<1)){if(!User.activated)return Toast.show("Please activate WME Stroopwafel first.","danger");if(!this.isAnyAspectShown())return Toast.show("Please select at least one aspect.","danger");if(!this.savingMakesSense())return Toast.show("Your current selection would not update anything.");if(100<this.selection.length)return Toast.show("You can update up to 100 squares at a time.","danger");let e=$("#WME_Marker_Context_Save_Btn");e.removeClass("waze-btn-green"),e.addClass("waze-btn-disabled"),$("#WME_Marker_Context_Aspects").hide(),$("#WME_Marker_Context_Spinner").show(),this.save(),this.saving=!0}},save:function(){let t={};this.getShownAspects().forEach(e=>{"-"!==e.status&&(t[e.name]="+"===e.status)});let n={codes:[],activationKey:settings.activationKey};this.selection.forEach(function(e){e={plus_code:e.attributes.plusCode};n.codes.push({...e,...t})}),$.ajax({type:"POST",url:settings.serverURL+"/grid",data:JSON.stringify(n),contentType:"application/json",dataType:"json"}).done(()=>{GridData.checkForUpdates(!0),this.deactivate(),this.selection=[],Toast.show("Your changes were saved.","success")}).fail(()=>{Toast.show("Your changes could not be saved.","danger")}).always(()=>{this.saving=!1,this.updateSelection(this.selection),$("#WME_Marker_Context_Aspects").show(),$("#WME_Marker_Context_Spinner").hide()})},addAspectsHTML:function(){let n=$("#WME_Marker_Context_Aspects");this.aspects.forEach(e=>{let t=$("<tr></tr>");t.attr("id","Stroopwafel-Aspect-"+e.name),t.append($("<td><label>"+e.displayName+"</label></td>")),t.append($('<td><button class="waze-btn waze-btn-small waze-btn-green">+</button></td>')),n.append(t),t.find("button").click(()=>{this.onClickAspectButton(e.name)})})},updateAspectsHTML:function(){this.aspects.forEach(e=>{let t=$("#Stroopwafel-Aspect-"+e.name),n=t.find("button");switch(n.removeClass((e,t)=>(t.match(/(^|\s)waze-btn-\S+/g)||[]).join(" ")),n.removeAttr("title"),n.addClass("waze-btn-small"),e.status){case"x":n.addClass("waze-btn-red"),n.text("✕"),n.attr("title","Remove "+e.displayName);break;case"-":n.addClass("waze-btn-empty"),n.html("-");break;case"+":n.addClass("waze-btn-green"),n.text("+"),n.attr("title","Add "+e.displayName)}t.toggle(e.shown)});let e=$("#WME-Stroopwafel-Context-No-Aspects");this.isAnyAspectShown()?e.hide():e.css("display","block")},onClickAspectButton:function(t){let e=this.aspects.find(e=>e.name===t);switch(e.status){case"x":e.status="-";break;case"-":e.status="+";break;case"+":e.status="x"}this.updateAspectsHTML()},isAnyAspectShown:function(){return 1<=this.getShownAspects().length},getShownAspects:function(){return this.aspects.filter(e=>!0===e.shown)},savingMakesSense:function(){return 1<=this.getShownAspects().filter(e=>"-"!==e.status).length}},Toast={init:function(){log("Initializing toast."),$("#waze-map-container").append(HTML_TOAST)},show:function(e,t="default"){let n=$("<div></div>");n.addClass("WME_Marker_Toast"),n.addClass("WME_Marker_Toast_"+t),n.text(e),setTimeout(function(){n.fadeOut()},2500),$("#WME_Marker_Toasts").append(n)}}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment