WME JumpMaps LV

The script adds in the WME links to third party mapping systems (Google/Open Street Maps/HERE etc.)

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name WME JumpMaps LV
// @description The script adds in the WME links to third party mapping systems (Google/Open Street Maps/HERE etc.)
// @license MIT
// @match https://*.waze.com/*editor*
// @match https://www.kadastrs.lv/map/*
// @match https://kartes.lgia.gov.lv/*
// @match https://*.balticmaps.eu/*
// @require https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.11.0/proj4.js
// @require https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js
// @require https://unpkg.com/[email protected]/dist/leaflet.js
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAAXNSR0IB2cksfwAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAK2BJREFUeJztXQd8jWcXf0MSxIo9a7f2VkpLlbY61Kg9v2pVKdpSqkpbtEptgpLYmxhF7FixRYKE7L333pL7/8553nuTe8ONkDuivL/faeom9973Oed/9nmeV5IMcMWkZliGJ6f1CElKHROQkDLfNz55g3dc0iHP2CQHj5hEN7foxOCHUQnRrlHxSS6R8ZlECiLc/2+R4r68Nl5jNP1/MP10ozU70NoPuUUnbHCPSZxPfBnjG5fUPTgx1dIQstHLFZMmBD4kKDHFhoTtRkJW3I+Ix52wWNwIicbVoChcDozExYAInPePwDm/cJzxDcNpnzCcegnoJJO3/JP/zWs/6xsu+HCB+HGJeHM9OFrhGBbrdjcizobAMdg/Prl4AyI+PbNUZEr6aBL6Ce/YpCzW4NuhsULYvKgztMCTPqE45hWCwx5BOOgehANugdj3MAB7HgRgl6u/oJ0vEfF6dxPtpfUzH/Y/DBQ8sXWT+cN8OuoZIkBCCpN1MzTGjizHKLIQpYwt79yLBG8RkZL+Y2BCSighFYRaXCGhM5rtvEJxiBbCC9zh4o+t93xhc9cHG5298c8dL6wjWuvoCSuiNUy3Xy7idfP6mQ/rif5x8ha8YR5tJl5tu+9HfPMTQGEeMkAYEKRQIY5hMdO9YpMsjCb4WGHm0xcEJaYGkw8X2n4xIBInvEMFgneSwDfRQv5x8hILXXXLAyuJlt90xzKipTdU5IYlLyktzSXiyQ2ZL8yfFbfcBb8YJGsdZWBYO8ug2HrfF9sJGGwxzvqGBV0LjppP7rWiwQSfkJFpEp2a0TI0KfUm+XbcDY+DQ2CUMO9svhi1G+iG+eZX0CJkYdOCr8v0t6CHr+iJJPNH8EoJjmVKQKy+7SEUiS0FWwlrUq4td32FZbD3i7hxKzSm5cPoBP0KPy49w4z8/EiK5H1coxI4UBGm/rBHMLa7sOC9xI0uVxO68Zn6opPMR+Yn83WlmmVgMLCysWs94hHkTUH1CAq0zfQifIrsy1Nk/4dPXHKyE2n9BYrgj5Dg2T/xTawiwbMZeyV0/YNhGYFhxU3ZKqhiiXUEiF0u/kmUSc2nYLGcroVfiUy+jWdMYhaZGpymtIV9kDWZIiu6AUbmK8EbllRAkK2Cijw4gMw66RO+8VZ4XCWdCD86LZ2En7bbPTox+waZfA7ydpK558h1hdLUG5sZLy/luQcRRCoDSpt7ftmn/SN33YlMLBoI2Oyz5rPw2d8fpxx+G0WhbHKWvcCCX3TVBfPsb2P28UuYcfA0frQ9hSnbD2LSpj300xbT958Qr886eh6/nb2BPy/fNfo9P41UgaOwDGQJtrgGZNsHx268H5v6fO6A0jyzsOS0BRTpZ6mEz8HGGvI7L4rWL772AH853BeCnrh5L0YtscLH039G93ET0LbfQDR5uwfqtmuPOm3bwfK1eihbpQr9fA21WrUWrzfo0hUtP/oUXUaMxQdTpmPIgqX4esMOAsYFLHS4Jz7f2GvUJGUWQVZg5R1v7HIPzboSkTjPMyXr2QLD+PRMiQK+Yd5xSUk3Q2JgR2afNf9FEP6iq674/exNTN11GJ/MmIOOA4egQee3ULlBQ5SxtIRpqVIoaWaGEqamKFGyJExKlJDJxAS0dEj008RE+VqJkuJvSpiaoaS5OUqVK4eKdeqifsfOaN9vEPpM+xnjCRBzTjgIoBl77SpiS7DsFmUKd/1xyC8q6U5c+tDgLBQeAFEp6S3845O9uHbPAR/7fDb7xVn4f15yxrR9dug3ZwGa9/4QVRo2QukKFYSghXBVAiYyMZFQooSEkkSmJWUyYzKVf6peM1X+TQkTKfe98vtNCBimKFW+PCrWqo36nTqj5zdTyMrsE+AzNi/YCiyl+GzVHR9YPwjG2bBET/fUR80KJfzo1AzLoMTU69zB4kYNFxo44CuuPn/BhTtklnfi7bHjUb1pM5QuLwtdJXAWNguytLmEcmUkVKsooXk9Ce+0ktC/m4TR70v44kMJUwdI+GWEhO8H0r/7SBj7gYQhPSR80EFChyYS6lSVUNFCQhlzGRwmaqBga2FWpgwq1q6DVh9/hqELVwirYDwXIbuB5VwvuOeP3T5RuBmffiXwESo8FQCh5PcfRieIej43IzjV42jf2ILOTxycjfh7NToNHo4qZN7ZtKvMuIkka3Ll8hIa15LQu72EiX0l/P21hH1zJNgvlXBnvQSv7RJC90uIsJWQeFxC5lkJSXb074MSwg9I8N8lwdVGwpVVEv6dL2H9VAk/fC7hw44SXq8joUp5GVh5FsJEuIyyVaqiSfd30X/uH5hz0sFoIFh60wOrnHyx8WEIjgTFwyU1e16BwqfAz8IvPjmEGzrcouSOFef5xc30/2J3mUzuVFRr8gbMy5bVEDyb7PKk6W+QgMb0loV2aZkEz20SYo5IyDonIecC0UUJiktqdFmN1F7nv2PKPi8hmcDht1PCVQLE5h9lS9HpDQJCBQnmpppWga0Qxwtdx4zDzCPnjAIAtgIrHL2x3iUI272jcD0+MzgO0N5AopRvOpt+bupwO5IrfMuKkfZzOjZ00QrUbt1WmFx1wbMAXqsm4eM3JSydIGt49GEJGWfUhH1ZB8SgIMo8JwPKlwCxn6zK/8hltCDXUq60JhDMSpcm19Qc/cgacPZgaBBwMLiGgkFr9zAcCU2Cd5Zi+hOFTzm/mW9cchCnfNzG5aYOd6SKS4Vv+sFTeHPYSFhYVtIQPPvjetVJ28mX758rIXgvaflZpdB1IfBCAIKtQ+IxchUrJcwaJqFtI4oVSuUBge+XM4jXOnTCyKVWIoU0FAA4GFxJweA/rsHY4RcLx5TsoBTg8bSQfP8Q1n57vwjsexgo2rhcXTK24DmtG7V8HeXmbSh9M8/TLBJ8w5oShveUcHie7LNZEDrT9OcgBh3HENdXS/h5uBwnmJupZw8lUIGyBs4Y5p66ahD+cUrIwaDVvQBs9orEqegMhCkw+DEAkO8/cT0kGsc85YIPNxqMrf0c4b8/9UeUr1FDRNqSMqrn4Kt/VwnH/5AQsk/CI3vjCv5JQOCg0n6JhFG9KPOwVAsUldag5cd9MW3/CQNkCnIwuNrZF9ZuYbANTYZHFo5rCJ/y/qpu0QmPuMO3X6n9y43s+389cx0dh46kXL5ibkrH5r5VA4rmx0sI3KPU+Ocx9Zfk94lgkOm8ki7oOFagzwslgFpNkVNJDk5V1sDU3Bz1OnXBBJvdegaBWjDoGoRdAfFwTMt5lAVUzgVAUGLKKC768FAHT5usNmLFj5kx2+4S2nw2QAR6KoZxcPVJZwl2f8rReKEFpYzk2UqknpQQ+68En+1yZnCAYgbraRL+HCfht9ESNv4gIWCXEgg6jBHSTsvfN22QXE9QWQPOFGq1bEVxwVosuuKiVxBwMMhuYLtvLM4lPEIsMDwXAD5xyTs47+f+virvN4b5X3zNFf9bY4PGlEOzhqgCPTb5nMc/sHkGc39JTvkiKad3Wi8HiHNHUZZAIGpRXw4ca1aSUJVSuAplZIBxkehnCuKiDsmRvi7dAlsrrjdYTZbQsr4cw4j1lSiJKo0aY9jilfjrir7KyXluYAulg8eiMxGkwNZcAJD597T3l82/XPUzjvn/ZvNe1OZgjyt5kqwptatI+JUEF7a/cJE9/03aKQn3rSXYTM9LzyqWlat4XCfgOMJE0izviu+j3w3opgSaLq2AGig5SNwzW8JbzSSUMs2rJFZt1ARjVm7QkzvIaxDZeITjUEQavLLhJoQfkZJmeS8iTnHKJ1QMcq4xUuFn6q5/0aBzV7mMqxR+o1oSVk6kfP7Q07WeBZ/Ogt8oYd5YCd1ayJVAIXCNOr782ayBFqT1FSwkVCon/21dAtv8/0mIO6Z7C6BOqXSfJ8iV9W4nobQyS+AKYu02bfG19S69gICzgRWOXtj4MBT7w1LgmoUcABXZ/3fjKR9Vu3elEXJ/7ru3+PATUc5VCalhDQlrJsv5dYHCvySXcD23SlhCwWGXZrK2qzdwTJQCZ1fS7DUJPVpLGNFLtiyrv5U18ugCCReXycUjfQpfdc8ZdM9nFsllarZMMghMRQua3aA+rMByigO4HrA3JAk3MxR4BHSV/OOTh10Ljsa/nsFijNvQ/p+7eB//OBvlq1UXBRMWFmsl+3y/XU8x+5dkbbq9Tg6wmtYls2qWp/El6bPKlpYtybtt5M/cPF3O0z22UQpJbiWKBJ5AIEs5QRbktAELSJdlS8OBJzen2FLxPXMzq2mvD8QMg64BwIMiXBbeE5QIhzQFUoFhknds0pxLytIvjxvL6Z9hALD4qqvwe1UbN5H775IcmI14T4IL+eHsAvww/85/t4TtP0l4v72m1jMz2aR3JTcwY7CEw79L8NomMzz9rPJzi0Pd4JIMwEVfSahfQ75/VgJzCwu8/eUEoRy6BAAHgmvvB2BXYALOp+QgAfhFco9JXG/vFy7n/xwAGjD//2HvcQ2/b0lCnPCphBtrlDm+FsZxdH93g4RvPpW1PjeiVloPDrAWjpM/J+6o/FmG1OxnIXY3gXsl/EhArVYhz3px8WvY4lU6BoA7rO76Y4d/HM4k5SAKWCs9iEo4wkMfqr7/UgNlAL+fu4UuI8cKtAvTZy7n+ddWy/5RG8P4dxeXShj4tixsldYzCJrUlvDDQLlbl3Bcx/m8Hoktkou1bPnYZakyg7rtO2C67UmdAmCNsx+2+8XiZEI2woFD0v3IeIeT3qFik+JaA039cL4/nNDN7VKu8nH61aah3KtPPV2A8M9IOPe3PKRR2jwvyLMoJQd2W2ZICLct2HoUV+Lu4qnF8qCKKjMwK2OBzqQkunEFcirItYDtvjE4QQAIAS5KlAK62HnLKaChxr5+OnIOr7/7Xq7pr2EpV+LYH2rzzVn2Es6T5r/fQQ70VKkip3Ajekq4QBF8yknt738RKOmEXDZu1yjPsvHI2f/WWOsOAE6+2OZDWV/8Iy4GOUt3I+L8OAXkXahcA1iiZwBwteuTGb+gjGUl2fSTMAeQOb9nrd1Ps4l0Jp8/6B21vLmEHN1P7S/hwSY5LjC2AItKHA/47JRL01yVVKWGnBXoYtaQAbDKyQdbvKNxLO4RAhTwlpzD48K4A6jqAegbANP22+G19h3laVsTOYjbOUuul2tjjB9F+199JJdrVcLnUa8VE+WxroKyhReN2BVwPMCDLebKSmGZipY6CQjlaiABwCsKR2Oz4JeDUMkpLDaOawBbeQBEzwDg0ekPvp8ppnVVvvvrT+QoWJvp5tTtry/JTVSSI2SO9HnyhzuCPJHzXxK+oEtyqrrpR0oNq+dVCZv0eE/MQeoCAJvzABArOYbGJnMTiKuA+gbAzMNnUf/Nzso5fLlGb/sbod7+ycxgv88VutYN83wi5/czh0gIO1AMhKVHCtgtD7uoUlweNB3+92qdAsA3B0nS7dCYdEMAgOvbo1esF0GNpJzhG9Rdgud27aXXSAoKJ/eXLYVqHuC9tnIl70WM9J+F0ijjWfaNXL4WxS1zc3QaOlJMSOkQAGkMgKzDBgDAnJNXxAJ4Vw4viCtf3K3TlvblEJ38Sy6Tqkw/B307ZsnpoLEFpG9ipeDB1rdb5s0WVnujKabZntIZAHxykCndConJYQBs0TMARi1fj1otW4tSJ2vyR50o2NksafX9DIC9cyTUrSozoLyFXO/nXr2xhWMoSrCTG1Zc8JLrAmXQd/Y8XQIgmwGg0DcAFl1zRftBw8RWKl4I5+7csuUAT6sGED2k9G5kLzlT4CoZl39f5Dz/eawA1z7eqKucYSDlad7nk+ferawBgBgBgByJW8H6BsCsYxfEjluxKdNEDv6O//n0CJ79PM/U3bZSm/otBoIxGDlQMEgZ0uDueSlhpXr18T2l0roAgHcOFBwD6B0AY1ZtROmKFeVOl5mEYe/K+XuhmKBt985LQukU7ywer+YGLCwwYN5furIA0DsA2Pz3mDA5d8yLmx0zh8oanduD/6/l8s9AvHbmAZexn0gn5HnGRjWVW9/IirYbOBgLLz/75hKDAeCPS874YrWN2Krdc9J3qPZ609zdPAyAPp3kjRNzR8rVvHsb5Jzf2MIwNPGaHSnSX/K1hDnEizmjnkD0+pcfycUvE+UuI96FzEo1hgLrSVsPCH4XKwAMJBNVtnIVofVcxVLfm68q5ar24FtSQDiln4QQW+MLxNAUsEfCuD7ytnXTktop/1yj6KASX3mErnzNWmjXfxAmbz/41FlCgwGAb0iV76tGu+UoNh8pm0HDekrwJWZw0GNsoRiKOMu5byPX/MV5A9p4pIXUFYp5XaNZC1Fo41a7UQHAKGz1cd9cn88CrlVZQr1q8ix+Lin/3bmphA3fS0i0M75QDE3xlAYv/VreTKrBm6cQu4PqFZXzjyZ5/YK67Triu93/Fi8AcNdu+iDZz+Un3sa982e57p1dTEe29EmPzsvTzFtnyLx4Eo+eRHzQxa+jJXzWVd4gqxoo5TOQeMBW2wYTgwOA0dmzrdze5NFtbnXmJw6Eiuu8niGI1848eBJvCiLOHDy2ykE0j8JxfYWtAM9YapsoNgoAeO6dUW5sRv8XicHDrXQOJFUjcpb16mPStgOvAPCyUDJZgoVfyuV1BkCFWrUwVsvGklcA+A9Swkl506tq6zkfQPE/q03FBwC92hEAtih7/q9Ip8S7ovhYGj61zKykXCSqzi1jLb0CowCAN2meXyIhaK98fs8rKjrx4Rj3NsrzFDxUo9J+01Kl0XHQUMw/71g8ACCGGCrKCOVDFwe/Ip0QC52zK56VUG0sVW0xH7d2s9aKoMEqgXy6R0nTvEqgSFFKvCKdkonmSaUVa9XBpzPnFriJxGAAeP+7GShVrrw4/cIkXx9AUjY0StBNl6S89RU9mbTxjYVdQnmINZeAzS3KonbL1uJUUj5UqyC5GAwAfCBiu8+HomqTN2BRqVLuCV+yNTBBJXqtYaPGaNzk9VekhapXryGUJE/4JcT+AD71vCr9vk679mja5yP0mjwN326zLdTxMgadB+BAZOKWfeI4NNXBD6I3ULoMRowcjd37bHHg0L+v6Alke/gYZvw0m0BQXaPh83rPXhi/cSem7jyMaQdOYN752880JWyUgZBu/xsvjkuVu4ImqFmrFlZbrUN8chpSM3Ne0ZMoKwenz55H23Ydcl2BKQGg45ARRTo+xuAA+OuKi0ZAyIt5441m2LV3P5LTM5GWBb1SKlOmQpC+v0vrPSi//1nuIT0buOHohB4939OIBXhDrc72BRgCADypInYB557yaYLWbdri8FE7AkCW3pienJGDiJhEPHDzxrVbTrhz7wECgiMQn5QuQGEIwSfSFwWEROLWnXu4ftMJLg+9EBweg6S0R08HwCPAzcsX/foP1ABAo3d6CKV6YQAwn3wUByt5k0Al0LlLV5w9fwkpGdl6YTwzmJn+/Q/T0bFjJzRr3hytWrXGBxQwrV2/EcFh0XoXPoNv5+796NdvAFq2bIVmzVqgXfsOFPuMgd2pc4hJSC3w/cQaePoEYsDngzUAUIdcwpwinDFseADY3xZHu6sDoOd7vUgj7ghfp2vG82ey8IeNGIWKyilkFXFqVb9+Ayz6eynCo+JAONG98Okz45JSsXHTVgE8U+XjalRUioLhd7q/i2MnziCJLIS2e2AL4B8cLtahDoBarduIEfsXGgDv9eqNm7eddQ8AYloYCfbX3+ejcuUqj+XQqu9v3aYNTp6x14sFYs29c/c+gby3EP6T7sGC8vYvx0+Ap2+A+HttnxUTn4TxX0/USAVfAaAASn+kIOa7oG+//jBTO1Y+P1WpUlVYgdjEZKFpugRgCn3gvv0HUYePvtHy/azRbcktXrzsoBUAwgIEhmLosBGvLMCzAOCiw1V07fq2MPfaBFCmjAWmTP2B/HSsTgHAn5WYmgHrTdtEEUfb9zO90bQZzpy1R6YWAGiLAQQAjl98BYACLcBnbAHMtDKfq5AL/viLArEknQMgmf6za+8B1K5du0ALwJnQ+YuXtQKA00APb3/0H/C5BgDqd34L8y88udP30gOATXBQWBSm/TgT5cqV08r8xo2b4ODhY0JYug4EGQQO126g05tvarVCXAn9fPAQ3H/gXqALuHPXFe+//6EGAPgU9ReqDmBQAGTJJtj28FF0Jk0xNzd/TPicGXw5/mvSLj+9ZAEsuJDwaMz5dR5q8FNO8jV0ODBs1rwF1m/chKi4JK33kJGtwCWHa+hCKXPu85HoZ7MP+rxYlUBDA4ApPCoe23bswSeffoZatWqTzy8DS8tKaEX+c8LEb3GNUlCh/Xr4biZel6u7N37+Za4I9izJ5VhYWJBbqEMpYA8sX7kGvgEhWiuDDKJMAsChI0fRpMnreeChFPLtcV8XSR4GB8A8+1sGBwAzlgstt53uY/PWnViybCWs1m3A8RNn4e0fTMLXTwFKnVIychAYGokTp+2xhr576bJV2LxtF85fuoqwyLiCy8KPGAQ52GC9CVWqVs3lHZ+t0Hf27y8WAH45eUVsWVIHQG/yaywcfQFAHQgsbK4MJhOxUAxVBlYHAn+3uAe6F/7309+nQDS5h9lkQcqWLZvLu3LVqmPcui0vFgD44QcV1CJiDoy4vu3u5SsWakhhFASUhJRMxCWlI5F+FqZpw3/DtX5+T3xyRiEFW9j7yaYU0F/UAMzV2uiV6zfAtCKeG2xQAPCAQrcvxmvMAjCiv508FaHhkbotwjwvswmE7BY22GzBrNlzsdFmKzE/oEDrxML3CwzDVjLp/J4/Fi7C9VtOAhC6uKfktExcvnIN7dp1yK0C8s+G3d7ROuxZLAHA5qpy/foaUXiDBg3Jt21GfFKqfmrxz0AMwKjYBCxdvgoNGzUSwWK9evWw4M9FCI2MfbIl4PfEJWLdP9Zo3qKleE/FipYYOXoMpXWeKKpVSxepbCRlCTaoUbOmxjBI9/GTCtz5W2wAwA+B4GfhqY6Dza3AUST8YZ+PcUOPAeCzMtvHLwADPx+cWzhiTev29jv49/gpCiRTHnsP9w9u3XHGp30/00gzubLHkzwpGUWzAlwXuHXHSfQKSqs9Mo8DwJHL1xVZKfUCAM5L+bgSnkblZ/98OutX1GzRSnMqmBjbpk1bLFuxGpExCUbXfhUA/IOCMXLUGNGlyw22ypUTFbgTp8+RtifLwSNZA/b1rg+9MOvnOahZs5bGgQ0tW7XG8ZNn6G+Lll4mpKRjy/ad6PRmFw3LyecDzjxytngBgAU//cBJDJj7J94a9QVaf9QXddu0kw+D0hhmlMfA5i1YKMykMadz8gMgNjEFK1ev1ajd8/1yrNK9+7vidxcdruPqDUfs3LMfo0aPFbUF9Q6dGVmCIUOHwcPHr2j3RPfjGxCE8RMmomrVannKU9IUHYeOEOcsFysA/H72BrqMGIvK9eqjDAmdgz11weeVPktjwOeDcNPRmaLmNKMLXpNycOHSFVFxy1+6Zf/++utvoCu5BC7gcP2+cuXKGsLn/69F4F652gqxCUXrLrJbvHL9Ft7t2UvDvbD57//bQp3EZToFAPt5Pvf3SfPrKuKFvPteL5w6e16v1beiaB37+rUU1HGA+qTegTrl/x1X98aMHQc3T98i30s0BZd/LFz8WAmZ3elP5FqLHQC++mcbyquNLasTawb7Ui7HnjhlT74tw/jCLoBCI+NEfMLZQEGtZPV6Rp26dTFz1i8U1N4tch2AtZ/dzPsf9NEYJDEl69l17Fc6e5CkTgEwddcRVGnYSHPTB/1/tWrV8dZb3TBn7u9wdHbRWX6sb+Jpos3bdqB7j3fFGkqXKi3Wo24BWDjcTma3sMpqHfns0KKXlskKRVA6unDR3yIW4dF5wU/6PsvX6mHi1v06Eb7OATD31FU06/1h7sw/kwUFT19TEOPs8lB0u3RZITMEcWXP+b4brDdvxzeTJpNGfog3KSLngU4GxuChw/H30hW47eQiXIcuAtpkyv3sLzqIoFN9joFz/07DRhWp/fs0AHgXBQB8Y5/MnCOeb6duAd7s0gUXLl954YSvIu4XsFbHJqTCyy+Igte7uHz1pujwhUfHi7q+LjMZn4AQfPfDj7C0tNRwM5XqN8Ck7bY6E74WACikWyHRz10H+NH2FFr3HaBR8OEUauK3UyjHDje6MHUCCNXGDj18dnR8MlmbbaKQpJ5dmFLw3GPCtzrVfi0uIIcB8NzHxfMmhXHrt4pOlTp6G1JssNFmC+KSi1vaV3yILckZ+0vo2as3zNVMv6l5KdRp0w4zDhe98FMgAGJzARCTXZRKIFcBuVBhqpa7cpTctdvbOG1/0SD99xeN2D0633+IUWPGirhJXXm46jdw/mKdC18LAMQDI7KK2gvgnao1xdNA8swYF4AGfj5EZAIvajygD2J34ukbhBkzf5ajfrWcnx8M9cmMOYU+/LmoAPDlR8bwQ6N00Qwa8ucylOMSptqCeBRr0uSpcPP0KzYlYKMKP0uBgJBw/D7vD7F3QF344nyfwcN18oDIpwFgSx4AxEOjknUBAE4LW370qXi6lbor4Lm2xZQ6BYVGvfTugFPjPfsPir0L6uVerqXUbNYC4zds11nR5+kAeJT72Li4Q+5BOmkHf7fnKOryIINaVsDHmTR5/Q0sXrIC91w9ngsEqgmc2MQ0kX/LlCpek91L8bYuqiGSHbv3oXuPnihVKq92wlag0mv1hAUtys7fZwKAd5R4dKyfArH8zKAwBsBmHQCA0fuF1WZUI4GrVwiFJaDXJk/9nmIC10JXBzlSDo2IxZXrt0VWwe8fM/YLQVxwWm31D47anYaHT4Ao4qQVQzfDgHf38scvc39Dx05vkuaX0hB+uerV8eH3M7HgYsHn++gKAPzs4K3i4dHZ8FcglC2Ar8oC6OLZwZy7jlxihaqNGj9WJuZu2vARo3D+4hXlFuknC4w1huvztoeOom/ffqhZs+YTa/SCgeXKiVkDnuR54O5TqP33hiKeNeRCElcVa9SoqVHnF21nipl6TpiiV7+fHwDi8fF+seLx8YEK+EiOYTH3D3sEiQdHrtbR08MFCJYqQaAW6AiBlS8vJoO37dwj4oL8GUJ8cjpc3LxEX7yC8hnDhSFmLm8IOUCgiUs0bv2BAcxVw0P/2onhEtVWdU3hVxXC/+1M0Z4HXHhSPj7e2Q87/ONwMjEHwcBdAkDsZQ4Ct92XHx+/VEczgYuuumDEkjXi8ML8cwJc827RspXYQXPL6b7w7cw0/nng4L8EkA80KmPPQtyi5Vn86PjHR7oMpfV8GsjCxUvQvkNHkQ5rWC1aVwWyBr0mfUfCv24g4csAWHrTHWvu+mNnQDxOJ+UgDLgoOYXHHjmiBICVo+4AoALBaOUTQ3myJX/LmCdfPus/AFt37BZ+8hj586bNmj2X4NWparVq9Jm7kJCq/3OIVJREvp6PodlPAOaRbjb5JUtoui3mQZWGjfHZz7+LXVOGE34eANbeD8DuoEScTVEgEjgoOYfHrWcAbM8FgLtOv5gDw0lb9qFJ954oW6XKY+NipSgoatS4iTg6joOkggZMnoX4hI6rN27rdQA1hbMT0vjAkEhx6seU76ahadNmYsYwv8nngzPrdXgTo5atw8LnfPJn0QHggXUuQdgXkozzaUAssEa6HxH3y1HPYOxw8cNaRy8su6lbAKjopyPnxFGmHBeUyHd6BjOID3XQlfBVFoYzhej4JJ37dw402cffdXUX08Bfjf9G7D0sSwHpY5NDbPJr1kKPryZiys5DOm/wPAsAlt3yxD8PgnEgPA0OGWS1gFnSg6iEYce9QgQA1t9RAUA/D5DmvsGX67agee8+4vk2uhT4k6hu3ddw8co18OxfUQTOgaos9ATcuftAxCmc1vFRMA0aNhLHvmhbS8U6dTH0rxX446KTkQQvEwf3y297wdo9DIeiMnCT1kYYGCx5xCR2O+UTKgDwj5MXlusRAEzsEr7b8y/a9vtcpEEmhRjBel7iYHP9RmtxJJ36eX0FEQub5/85f+dR8ODwaJFeXnC4LjZ48sx+mzbtxDlE/PlPA3Gt5i2f+2HPugbACkdvbPaMxL8xWbibDSiAtyS/+OSK5/3DFTtd/LHByRsrbnlgiR4BoCLWCPaHvOXJ3MJCbyD4+JO+OHTkOPno04WgM+II23X/2ODvZSsx86fZGDJ0uIhNKlP8Ymqq/eQRbcSTPb/YXS4GAOAikC+2+cbCLiEHXjnIAVBB4utyYKQbA2CjszdWEQB0mQk8jfgJV83fe19vAOC9+Y0aNxaVyCZNnkL0N6+9Vk9sy+YC0/Omovlp9BIrIwNADgDX3gvAHsoAzlAGEAy4SarrRkj05t0PAmDt7COqgYYEAO936zp0lN4AwJR/vPtppOvv7/PtNKMDgP3/hgchsKUA8GK6yABscgFwNzx2qK1bIKzv+ohUkANBQ7gBGQAP0HXYaL0CwNjUa9xEowJA1QNQdQFvP1IGgKrLMybR8qR3aJYNAYBTwRW33HV+anhBAHhn1Dj9aT+ZcZ6vNytdRitxL16fGUnvLycZVfs5/Vt3PxC7AxNwKkkBHwUoB0BFSf26GBBxdPM9H6yjVHClgeOAvjPm6I35/BStrl9OwDsTJ2ulLl98hXJPOduvKDRo9gIjar8bVt3xgY1HOA5GpOMCmf8o4IiU/3IMjR2y29VfAIDbwssN6AYmbNghKmU6137S6j4/zcHCG/Q9DOibTyB6/Y/rrmjVf6DeAPDdVt2Odz+L9ovgj7R/V0C8aAE7UfqXCXz+GADcoxPN7LxDgteRC+BMQADAQFaAD5Nq0OFNnTO+Qs2amLhf+9O01WnQyrV6EX75KtWMqv0r73hjk2cEDkam41wqEAQEkvk3fQwAfDkERv24ieKAlUoAyG7AMCAY9NtfImfWJfM7UA6/4ErhijBzLt4Wz+PRNQDeG1u0o92Kov3LbnHtP1CkficSc3CTzzMGpj1R+Hy5RiVYHPEIDmYLsOyGDABDuQEeini9W3edMV7srDlwrNDfv5jcxGfz/9Kp8MuUr4DfTj7/+f5FEb7o/Tv5Yot3tKj8se8PEuk/LLQCgK9zfuELbJx9RFdwiQEBwNnA2OXrYVlT+zm7haVSFmXxwfczMd/h2UqwP5+9hjrNW+kMAD1GfGEE4csAWM6NH9dg7A1Josg/R/j+BGB+gcLn605YrOVJn/Dr6528la1hw2UDTBOstqB+m/bPzfTSFEwOmPErFj3ngOWMfSdQvUGjIgu/cYfO+KOIp3o9r/A58LO6548dfrFi+PM6JX2RwFVF/tRP23UjLK75Ia9QrzUEAvYjS3KBYBgwsNns9MkA8aSsZ2F6tXoNMGbR6ucWvopmHTyD5m/31JhufhZq+tY7+NXOwUjCl+f+uOhzOCoDF9IAXwU8yQM0K5Tw+fKIT5GuhMUN3+cZmryGPozLiEtzswLDgOCvy/eEMOu3bg8ztUOc8hOnepY1aqH78LH46cApnX3/vDM30HP0V7CoUPGZrA+/Z4HBp33yhM8Vv00eEbCNSBNTPw9ykJQIDCXfX2j5i+tBXKqZQ3jCgt2eYVlryZysdFRZA8OBgGkBmdFJG3bh42+no02vj9C4YxdhXllDe4+biBHzlmCW7WlxPJ2uv5styWSbPej4cX9Url33sbE2Jt73ULlWHXT4qB+mbNpnBMGrC99XFHwOhKfiVLICztnIigHmkfDNnk36KhAkZpR3iEjatMc7Ins9pRP8BcvF5LBhXYKxicE1+7A9vlm3DQMpvvhg/BR8+PVUDPttEb22HT8fPmc0wat8Ppt9zvdl4efA8RGyye9vJPdf7rmEr7oeJmdVuhqdsmu/X3Q2d5Os7iqtwU3DxwavSFP4zH9WSKt7AWK3D5t91nwWfgSwi4RfqUjCV10eqdmVbsalWx8Ois/aTCZmvWuQmC9fwTOERggSX25yE26Y+c5azzN+POd/ODpT+Hw2+6T51joTvuryyVSUc07Omn86IiV5J6UXNu4EBJcgrLn7CgiGFDybe97fx7zf6hMtJnw51eNonwM+8vnzi2z2tV0hCpi5Z+SMuJqQ6XMkLFnkmZu9IgUKGQhcd+bWo2bG8AoMRRe6u+ArR/hc2mWe7w1OElu82eRznk+pnjdF+8OfO+Ar7EVfYhKcg5YPMnJunonNhG1oijBBPGy44WGI8Ed8oyqrIIMhPyDyk7EZbTwB5ydRfc0VuodIwbmky/P8HORxT5+nenlr14UMiAofmfxrlOe3eOZUryhXHGDpn40FLhmK4DNxWbANS6WbS8Q23xhKRSKEVeAZNPZTbBl4IYxiGRQyMPLA8fKSzAcPwRfmzwriE/OLYywe4tjoFipMPTd0DkVmiIHOc2Tubz0Snb0gLu8WusKnj4sAaBGhwHS3Rwi9nJIDO/JHhyLTsS80GbsIrQwItg7WbmFiJo19F/en2VLwPjUGCKeXbDVeHvIVAub1Mx+YH+tdg7HxYahQHo7od5JVZf/OQj8Wly1MPTd07mQLwZPdxXTS+DJGE3z+i26mFLmH0cEKnHB/hKxrGQqcpXz0ePwjHKEIlfvRnKMyMPaQ/+L9aTykwO6Dtytv981PMf8xylsbx047/eOFgjAvWNAHyIIyj47EZAmBc/v2bCpwicy8Iz/bQCGiezv65yjmtbHlXeBFN2hJYB0SDWwKVMDNIxuKO7SIa5kQE6n2qQqRsvAOVfZlJ8is2SVkvySUI4R7ktbOWs0j2vYkaNZuB+IP79jhTRteOVDw6DZP7/IAJ/PU2HJ97otvPgfoTq5rDFmJ+ZSqbIgADoXSmsmcuQUoEOyvQLSfAklEmb60eIpq8Z8iWhOvjdfIa+U1s4DDiAek2YeYJ8wbwsEY5pWhBP5/ZW++8V91mIcAAAAASUVORK5CYII=
// @version 6.0
// @author skirda, alexletov, N190392
// @namespace https://greasyfork.org/en/scripts/481079-wme-jumpmaps
// ==/UserScript==

/* global W, WazeWrap */

var wmeJM_IconWME = GM_info.script.icon;
var wmeJM_version = GM_info.script.version;
console.log("WME-JumpMaps (" + wmeJM_version + "): Start");

var wmeJM_countProbe=0;
var wmeJM_countProbe2=0;
var wmeJM_countProbeWM=0;
var wmeJM_countProbeLOC=0;
var wmeJM_debug=false;
var wmeJM_restoreSelected=false;
var wmeJM_around=false;
var wmeJM_hideWindow = false;
var wmeJM_leftOffset = wmeJM_defaultLeftOffset;
var wmeJM_topOffset = wmeJM_defaultTopOffset;
var wmeJM_defaultLeftOffset = '0px';
var wmeJM_defaultTopOffset = '30px';
var wmeJM_showMinimap = __GetLocalStorageItem("WMEJumpMapsShowMinimap", 'bool', true);
var minimapInstance = null;

var wmeJM_Config={};
var wmeJM_Config0 = {
    "_map_WME":    {save:0, title:"Open in WME",						name:"[WME]",	template:'https://www.waze.com/editor/?env=row&zoomLevel={{zoom}}&lat={{lat}}&lon={{lon}}'},
    "_map_LI":     {save:0, title:"Open in LiveMap",					name:"[Live]",	template:'https://www.waze.com/livemap/?zoom={{zoom}}&lon={{lon}}&lat={{lat}}'},
    //-------------------------------------
    "_map_OSM":    {save:1, title:"OpenStreetMap",			    name:"OpenStreetMap",	template:'http://www.openstreetmap.org/#map={{zoom}}/{{lat}}/{{lon}}'},
    "_map_Google": {save:1, title:"Google Maps",				name:"Google",	template:'http://www.google.com/maps/?ll={{lat}}%2C{{lon}}&z={{zoom}}&t=m'},
    "_map_BING":   {save:1, title:"Bing Maps",					name:"Bing",	template:'http://www.bing.com/maps/?v=2&cp={{lat}}~{{lon}}&lvl={{zoom}}&dir=0&sty=h&form=LMLTEW'}, // sty: "h" - ariel, "r" - map
    "_map_HERE":   {save:1, title:"HERE WeGo",					name:"HERE",	template:'https://wego.here.com/?map={{lat}},{{lon}},{{zoom}},normal'}, // "hybrid.day" - ariel, "normal.day" - map
    "_map_APPLE":  {save:1, title:"Apple Maps",					name:"Apple",	template:'https://maps.apple.com/?ll={{lat}},{{lon}}&spn=0.0038614715299516433%2C0.010368359444299813'},
    "_map_MRY":    {save:1, title:"Mapillary",				    name:"Mapillary",	template:'https://www.mapillary.com/app/?lat={{lat}}&lng={{lon}}&z={{zoom}}'},
    "_map_WM":     {save:1, title:"Wikimapia",				    name:"Wikimapia",	template:'http://wikimapia.org/#lang=ru&lat={{lat}}&lon={{lon}}&z={{zoom}}&m=b'},
    "_map_SC":     {save:1, title:"MapCam",					name:"MapCam",	template:'http://mapcam.info/speedcam/?lng={{lon}}&lat={{lat}}&z={{zoom}}&t=OSM'},
    "_map_WMFLAB": {save:1, title:"GeoHack",    		        name:"GeoHack",	template:'https://tools.wmflabs.org/geohack/geohack.php?params={{lat}}_N_{{lon}}_E_scale:{{zoom}}'},
    "_map_OSV":    {save:1, title:"KartaView",			        name:"KartaView",	template:'http://kartaview.org/map/@{{lat}},{{lon}},{{zoom}}z'},
    "_map_RBASE":  {save:1, title:"RadarBase.info",				name:"RadarBase",	template:'https://radarbase.info/map/actual/{{lat}}/{{lon}}/{{zoom}}'},
    "_map_SPRO":   {save:1, title:"satellites.pro",				name:"SatPRO",	template:'https://satellites.pro/#{{lat}},{{lon}},{{zoom}}'},
    "_map_BM":     {save:1, title:"[LV] BalticMaps",			name:"BalticMaps",	template:'https://balticmaps.eu/lv/c___{{lon}}-{{lat}}-{{zoom}}/bl___cl'},
    "_map_LGIA":   {save:1, title:"[LV] LĢIA Kartes",			name:"LĢIA",	template:'https://kartes.lgia.gov.lv/?x={{lat}}&y={{lon}}&zoom={{zoom}}'},
    "_map_KDL":    {save:1, title:"[LV] Kadastrs",				name:"Kadastrs",	template:'https://www.kadastrs.lv/map/di?xy={{lat}},{{lon}}&z={{zoom}}'},
    "_map_LVM":    {save:1, title:"[LV] LVM GEO",	        	name:"LVM GEO",	template:'https://lvmgeo.lvm.lv/?loc={{lat}};{{lon}};{{zoom}}'},
    "_map_CFY":    {save:1, title:"[LV] Citify",         		name:"Citify",	template:'https://citify.eu/lv/?lng={{lon}}&lat={{lat}}&z={{zoom}}'},
    "_map_BIS":    {save:1, title:"[LV] BIS Plānotie būvdarbi",	name:"BIS",	template:'https://bis.gov.lv/bisp/lv/planned_constructions/bismap#x={{lon}}&y={{lat}}&z={{zoom}}'},
    "_map_LVC":    {save:1, title:"[LV] LVC Būvdarbi",			name:"LVC",	template:'https://map.transportdata.gov.lv/public?mode=summer#{{zoom}}/{{lat}}/{{lon}}'},
    "_map_DODLV":  {save:1, title:"[LV] Dodies.lv",				name:"Dodies",	template:'https://vesture.dodies.lv/#m={{zoom}}/{{lat}}/{{lon}}&l=J'},
};

var wmeJM_ArrW2B=[{w:7,b:-2},{w:6,b:-1},{w:5,b:0},{w:4,b:1},{w:3,b:2},{w:2,b:3},{w:1,b:4},{w:0,b:5}];
var wmeJM_ArrW2KDL=[{w:0,r:75000},{w:1,r:50000},{w:2,r:15000},{w:3,r:10000},{w:4,r:5000},{w:5,r:3000},{w:6,r:1000},{w:7,r:750},{w:8,r:500},{w:9,r:200}];

function WmeJM_GetFaviconURL(key, template) {
    try {
        // explicit icon property wins
        if (key && wmeJM_Config[key] && wmeJM_Config[key].icon) {
            return wmeJM_Config[key].icon;
        }
        // derive from template
        if (typeof template === 'string') {
            var m = template.match(/https?:\/\/([^\/]+)/);
            if (m && m[1]) {
                var domain = m[1].replace(/^www\./, '').replace(/^map\./, '');
                //return 'https://www.google.com/s2/favicons?sz=16&domain=' + encodeURIComponent(domain);
                return 'https://icons.duckduckgo.com/ip3/' + encodeURIComponent(domain) + '.ico';
            }
        }
    } catch (e) {
        console.error('WmeJM_GetFaviconURL error', e);
    }
    return '';
}

function cloneConfig(obj)
{
    if (null === obj || "object" != typeof obj) return obj;
    var copy = obj.constructor();
    for (var attr in obj)
    {
        if (obj.hasOwnProperty(attr))
        {
            copy[attr] = cloneConfig(obj[attr]);
        }
    }
    return copy;
}

function CreateID()
{
    return 'WME-JumpMaps-' + wmeJM_version.replace(/\./g,"-");
}

// NEW: Save only checkbox states
function WmeJM_SaveCheckboxStates()
{
    var states = {};
    for(var i in wmeJM_Config) {
        if(["_map_WME","_map_WMEB","_map_LI"].indexOf(i) < 0) {
            states[i] = wmeJM_Config[i].save;
        }
    }
    localStorage.setItem("WMEJumpMapsCheckboxStates", JSON.stringify(states));
}

// NEW: Load only checkbox states
function WmeJM_LoadCheckboxStates()
{
    var states = localStorage.getItem("WMEJumpMapsCheckboxStates");
    if(states) {
        states = JSON.parse(states);
        for(var i in states) {
            if(wmeJM_Config[i]) {
                wmeJM_Config[i].save = states[i];
            }
        }
    }
}

// OLD function - now just returns empty string since we don't save templates
function WmeJM_Config2String()
{
    return "";
}

function getElementsByClassName(classname, node)
{
    if(!node)
        node = document.getElementsByTagName("body")[0];
    var a = [];
    var re = new RegExp('\\b' + classname + '\\b');
    var els = node.getElementsByTagName("*");
    for (var i=0,j=els.length; i<j; i++)
        if (re.test(els[i].className)) a.push(els[i]);
    return a;
}

function wmer_generate_permalink() {
    var wcp=document.getElementsByClassName('WazeControlPermalink');
    for(var i=0; i < wcp.length; ++i)
        for (var j=0; j < wcp[i].getElementsByTagName('a').length;++j)
        {
            var href=wcp[i].getElementsByTagName('a')[j].href;
            if (href.indexOf(".waze.com/") > 0 && href.indexOf("/editor") > 0)
            {
                // kill "/ru/", kill "layers"
                href=href.replace("/ru/","/").replace(/layers=([0-9]+)\&/,"") + "&marker=yes";
                return href;
            }
        }
    return "";
}

// Helper function to extract query string parameter
function __getQueryString(link, name) {
    if (link.indexOf(name + '=') <= 0) return -1;
    var pos = link.indexOf(name + '=') + name.length + 1;
    var len = link.substr(pos).indexOf('&');
    return (len == -1) ? link.substr(pos) : link.substr(pos, len);
}

// Site configuration - maps hostname to site type
const SITE_CONFIG = {
    'www.waze.com': 'waze',
    'editor-beta.waze.com': 'waze',
    'beta.waze.com': 'waze',
    'balticmaps.eu': 'balticmaps',
    'www.kadastrs.lv': 'kdlv'
};

// Get current site type
function WmeJM_GetLocationType() {
    const hostname = location.hostname;

    // Direct match
    if (SITE_CONFIG[hostname]) return SITE_CONFIG[hostname];

    // Google domains (www.google.*)
    if (hostname.startsWith('www.google.')) return 'google';

    if (wmeJM_debug) console.log("WME-JumpMaps: Unknown site type for " + hostname);
    return "";
}

// Extract lat/lon/zoom from current page
function WmeJM_GetLLZ() {
    const href = location.href;
    const locType = WmeJM_GetLocationType();
    let lat = 0, lon = 0, zoom = 0, city = '';

    const extractors = {
        waze: () => {
            const urPos = new OpenLayers.LonLat(W.map.getCenter().lon, W.map.getCenter().lat);
            urPos.transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326"));
            return {lat: urPos.lat, lon: urPos.lon, zoom: W.map.getZoom()};
        },

        osm: () => {
            const xy = OSM.mapParams();
            return {lat: xy.lat, lon: xy.lon, zoom: xy.zoom};
        },

        google: () => {
            const i2 = href.indexOf("@");
            if (i2 >= 0) {
                const l = href.substr(i2 + 1).split(",");
                const zoomAttr = l[2].replace(/([0-9]+)([zm]+)(\/.*)?\.*/, '$1.$2').split(".");

                if (zoomAttr[1] === "m") {
                    const ArrM2Z = [
                        {z:1,m:51510000},{z:2,m:25755000},{z:3,m:12877500},{z:4,m:6438750},{z:5,m:3219375},
                        {z:6,m:1609687},{z:7,m:804844},{z:8,m:402422},{z:9,m:201211},{z:10,m:100605},
                        {z:11,m:50303},{z:12,m:25151},{z:13,m:12576},{z:14,m:6288},{z:15,m:3144},
                        {z:16,m:1572},{z:17,m:786},{z:18,m:393},{z:19,m:196},{z:20,m:98},
                        {z:21,m:49},{z:22,m:25},{z:23,m:12}
                    ];
                    const z = parseInt(zoomAttr[0]);
                    let calculatedZoom = 1;
                    for (let i = 0; i < ArrM2Z.length - 1; i++) {
                        if (z <= ArrM2Z[i].m && z >= ArrM2Z[i + 1].m) {
                            calculatedZoom = ArrM2Z[i].z;
                            break;
                        }
                    }
                    return {lat: l[0], lon: l[1], zoom: calculatedZoom};
                }
                return {lat: l[0], lon: l[1], zoom: zoomAttr[0]};
            }
            return {
                lat: __getQueryString(href, 'y'),
                lon: __getQueryString(href, 'x'),
                zoom: parseInt(__getQueryString(href, 'z'))
            };
        },

        balticmaps: () => {
            const res = Array.from(href.matchAll(/http(s)?:\/\/balticmaps\.eu\/\S+\/c___(\d+(\.\d+)?)-(\d+(\.\d+)?)-(\d+)\/.*/g));
            return {lat: res[0][2], lon: res[0][4], zoom: res[0][6]};
        },

        lgia: () => {
            const resp = Array.from(href.matchAll(/https:\/\/kartes\.lgia\.gov\.lv\/karte\/\?x=([0-9]*\.[0-9]+)&y=([0-9]*\.[0-9]+)&zoom=([0-9]+)/g));
            return {lat: resp[0][1], lon: resp[0][2], zoom: resp[0][3]};
        },

        kdlv: () => {
            let frmap = null;
            for (let ii = 0; ii < frames.length; ii++) {
                if (typeof frames[ii].esri !== "undefined") {
                    frmap = frames[ii];
                    break;
                }
            }
            if (frmap) {
                frmap.document.getElementById("dijit_form_Button_15").click();
                const urlKdl = frmap.document.getElementById("dijit_Dialog_0").getElementsByTagName("textarea")[0].value;
                frmap.document.getElementsByClassName("dijitDialogCloseIcon")[0].click();
                const ll = __getQueryString(urlKdl, 'xy').split(',');
                return {lat: ll[1], lon: ll[0], zoom: parseInt(__getQueryString(urlKdl, 'z'))};
            }
            return {lat: 0, lon: 0, zoom: 0};
        }
    };

    // Generic query string extractor for mry, wm, sc (lat/lng/z)
    if (['mry', 'sc'].includes(locType)) {
        lat = __getQueryString(href, 'lat');
        lon = __getQueryString(href, 'lng');
        zoom = parseInt(__getQueryString(href, 'z'));
    } else if (locType === 'wm') {
        lat = __getQueryString(href, 'lat');
        lon = __getQueryString(href, 'lon');
        zoom = parseInt(__getQueryString(href, 'z'));
    } else if (extractors[locType]) {
        const coords = extractors[locType]();
        lat = coords.lat;
        lon = coords.lon;
        zoom = coords.zoom;
    }

    if (wmeJM_debug) console.log(`WME-JumpMaps: GetLLZ (${locType}): lat=${lat}, lon=${lon}, zoom=${zoom}`);
    return {lat, lon, zoom, city};
}

// Transform coordinates FROM external sites TO WME
function WmeJM_Convert_Other2WME(llz) {
    if (wmeJM_debug) console.log("WME-JumpMaps: Convert_Other2WME", llz);

    const locType = WmeJM_GetLocationType();
    const LKS92_PROJ = "+proj=tmerc +lat_0=0 +lon_0=24 +k=0.9996 +x_0=500000 +y_0=-6000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs";

    const transformers = {
        lgia: () => {
            const transformed = proj4(proj4(LKS92_PROJ), proj4('EPSG:4326'), [parseFloat(llz.lon), parseFloat(llz.lat)]);
            llz.lon = transformed[0];
            llz.lat = transformed[1];
            llz.zoom = parseInt(llz.zoom, 10) + 7;
        },
        kdlv: () => {
            const transformed = proj4(proj4(LKS92_PROJ), proj4('EPSG:4326'), [parseFloat(llz.lon), parseFloat(llz.lat)]);
            llz.lon = transformed[0];
            llz.lat = transformed[1];
            llz.zoom = 17;
        },
        kadua: () => {
            const transformed = proj4(proj4('EPSG:900913'), proj4('EPSG:4326'), [parseFloat(llz.lat), parseFloat(llz.lon)]);
            llz.lon = transformed[0];
            llz.lat = transformed[1];
        },
        reglt: () => {
            const transformed = proj4(proj4('EPSG:3346'), proj4('EPSG:4326'), [parseFloat(llz.lon), parseFloat(llz.lat)]);
            llz.lon = transformed[0];
            llz.lat = transformed[1];
            for (let i = 0; i < wmeJM_ArrW2KDL.length - 1; i++) {
                if (llz.zoom >= wmeJM_ArrW2KDL[i + 1].r && llz.zoom <= wmeJM_ArrW2KDL[i].r) {
                    llz.zoom = wmeJM_ArrW2KDL[i].w;
                    break;
                }
            }
        }
    };

    if (transformers[locType]) transformers[locType]();

    if (wmeJM_debug) console.log("WME-JumpMaps: Converted:", llz);
    return llz;
}

// Transform coordinates FROM WME TO external sites
function WmeJM_Convert_WME2Other(id, llz) {
    if (wmeJM_debug) console.log(`WME-JumpMaps: Convert_WME2Other(${id})`, llz);

    llz.zoom = this.id == '_map_LI' ? llz.zoom - 1 : llz.zoom;
    const LKS92_PROJ = "+proj=tmerc +lat_0=0 +lon_0=24 +k=0.9996 +x_0=500000 +y_0=-6000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs";

    const transformers = {
        _map_Google: () => {
            if (location.href.indexOf("mapmaker") > 0) llz.zoom++;
        },
        _map_BM: () => {
            const urPos = new OpenLayers.LonLat(llz.lon, llz.lat);
            urPos.transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:3857"));
            llz.lat = urPos.lat;
            llz.lon = urPos.lon;
        },
        _map_LGIA: () => {
            const transformed = proj4(proj4('EPSG:4326'), proj4(LKS92_PROJ), [parseFloat(llz.lon), parseFloat(llz.lat)]);
            llz.lon = transformed[0];
            llz.lat = transformed[1];
            llz.zoom = 9;
        },
        _map_KDL: () => {
            const transformed = proj4(proj4("EPSG:4326"), proj4(LKS92_PROJ), [parseFloat(llz.lon), parseFloat(llz.lat)]);
            llz.lon = transformed[1];
            llz.lat = transformed[0];
            let zoom = llz.zoom - 12;
            if (zoom > 7) zoom = 7;
            for (let i = 0; i < wmeJM_ArrW2KDL.length; i++) {
                if (zoom == wmeJM_ArrW2KDL[i].w) {
                    zoom = wmeJM_ArrW2KDL[i].r;
                    break;
                }
            }
            llz.zoom = zoom;
        },
        _map_LVM: () => {
            const transformed = proj4(proj4('EPSG:4326'), proj4(LKS92_PROJ), [parseFloat(llz.lon), parseFloat(llz.lat)]);
            llz.lat = transformed[0];
            llz.lon = transformed[1];
            llz.zoom = 14;
        },
        _map_MRY: () => { llz.zoom--; },
        _map_WMFLAB: () => {
            const convertd2dms = (degrees) => {
                const mydegrees = parseInt(degrees);
                let remaining = degrees - mydegrees;
                const myminutes = parseInt(remaining * 60);
                remaining = (remaining * 60) - myminutes;
                const myseconds = Math.round(remaining * 60 * 10) / 10;
                return {d: mydegrees, m: myminutes, s: myseconds};
            };
            const la = convertd2dms(llz.lat);
            const lo = convertd2dms(llz.lon);
            llz.lat = `${la.d}_${la.m}_${la.s}`;
            llz.lon = `${lo.d}_${lo.m}_${lo.s}`;
            llz.zoom = Math.pow(2, 12 - llz.zoom) * 100000;
        },
        _map_OSV: () => { if (llz.zoom > 18) llz.zoom = 18; },
        _map_KADUA: () => {
            const urPos = new OpenLayers.LonLat(llz.lon, llz.lat);
            urPos.transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913"));
            llz.lat = urPos.lat;
            llz.lon = urPos.lon;
        },
        _map_REGLT: () => {
            const transformed = proj4(proj4('EPSG:4326'), proj4('EPSG:3346'), [parseFloat(llz.lon), parseFloat(llz.lat)]);
            llz.lon = transformed[1];
            llz.lat = transformed[0];
            let zoom = llz.zoom - 12;
            if (zoom > 7) zoom = 7;
            for (let i = 0; i < wmeJM_ArrW2KDL.length; i++) {
                if (zoom == wmeJM_ArrW2KDL[i].w) {
                    zoom = wmeJM_ArrW2KDL[i].r;
                    break;
                }
            }
            llz.zoom = zoom;
        }
    };

    if (transformers[id]) transformers[id]();

    if (wmeJM_debug) console.log("WME-JumpMaps: Converted to external:", llz);
    return llz;
}

// Post-load processing (currently empty for all sites)
function WmeJM_PostLoadOtherMaps() {
    if (wmeJM_debug) console.log("WME-JumpMaps: PostLoadOtherMaps");
    // Currently no post-load processing needed for any site
}

// Mouse click handler - jumping mechanism
function WmeJM_clickJumpToMaps()
{
    if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_clickJumpToMaps("+this.id+")");

    var savedSelectedItems=[];
    if (wmeJM_restoreSelected && !(this.id === '_map_WME' || this.id.indexOf("_map_WME_") >= 0 || this.id === '_map_WMEB'))
    {
        if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_clickJumpToMaps("+this.id+"): save selected");
        for( var i=0; i < W.selectionManager.getSelectedFeatures().length; ++i)
            savedSelectedItems.push(W.selectionManager.getSelectedFeatures()[i].model);
    }

    var llz=WmeJM_GetLLZ();
    if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_clickJumpToMaps("+this.id+"): llz="+JSON.stringify(llz));

    if (this.id == '_map_WME' || this.id == '_map_WMEB' || this.id.indexOf("_map_WME_") >= 0)
        llz=WmeJM_Convert_Other2WME(llz);
    else
        llz=WmeJM_Convert_WME2Other(this.id,llz);

    if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_clickJumpToMaps("+this.id+"): wmeJM_Config["+this.id+"]="+JSON.stringify(wmeJM_Config[this.id]));

    var template=(typeof wmeJM_Config[this.id] !== "undefined")?wmeJM_Config[this.id].template:"";
    if (this.id.indexOf("_map_WME_") >= 0)
        template=wmeJM_Config["_map_WME"].template;
    var url=template.replace("{{city}}",llz.city).replace("{{lon}}",llz.lon).replace("{{lat}}",llz.lat).replace("{{zoom}}",llz.zoom) + ((this.id == '_map_WME' || this.id.indexOf("_map_WME_") >= 0 || this.id == '_map_WMEB')?"&marker=yes":"");

    if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_clickJumpToMaps("+this.id+"): " + url + ', _url'+this.id);

    if(wmeJM_restoreSelected && !(this.id == '_map_WME' || this.id.indexOf("_map_WME_") >= 0 || this.id == '_map_WMEB')) // restore selections
    {
        if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_clickJumpToMaps("+this.id+"): restore selected");
        setTimeout(function() {if (savedSelectedItems.length > 0){W.selectionManager.select(savedSelectedItems);savedSelectedItems.length=0;}},50);
    }

    if (this.id.indexOf("_map_WME_") >= 0) // If it's something like that, jmlink - we kilay from the url of lats/longs/zooms...
    {
        if (this.getAttribute("jmfrom") === "mapbys") // If it's something like that, jmlink - we kilay from the url of lats/longs/zooms...
        {
            window.open("http://map.nca.by/map.html?xy="+this.getAttribute("jmlink")+"&z=16",'_url_jm'+this.id);
        }
        url=url.split("&")[0]+"&jmlink="+this.getAttribute("jmlink");
    }

    window.open(url,'_url'+this.id);
}

// Add JumpMaps floating menu to WazeMapEditor
function WmeJM_InsertWMEIcon()
{
    if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_InsertWMEIcon(): "+(document.getElementById('WME.JumpMaps_' + wmeJM_version)?"found":"none"));
    var nod=document.getElementById('WME.JumpMaps_' + wmeJM_version);
    if(nod)
    {
        // clear exist
        nod.innerHTML="";
    }
    else
    {
        // Create new template
        nod=document.createElement("div");
        nod.setAttribute('id', 'WME.JumpMaps_' + wmeJM_version);
        nod.setAttribute('unselectable', 'on');
        var leftPos = wmeJM_leftOffset;
        var topPos = wmeJM_topOffset;
        nod.setAttribute('style', ' font-size: 12px; color: #fff; padding-left: 20px; position:absolute; top:' + topPos + '; left:' + leftPos + '; display:block; background-color:rgba(0,0,0,.7); visibility:' + (wmeJM_hideWindow ? "hidden":"visible") + ';cursor:pointer;');
    }

    nod.innerHTML="";

    // Load checkbox states
    WmeJM_LoadCheckboxStates();

    var innerHTML="";
    for (let i in wmeJM_Config)
    {
        if (["_map_WME","_map_WMEB","_map_LI"].indexOf(i) < 0)
        {
            if (typeof wmeJM_Config[i] !== "undefined" && wmeJM_Config[i].save === 1)
            {
                // Resolve template for this entry (work with either aLinks or wmeJM_Config)
                const template = (typeof aLinks !== 'undefined' && aLinks[i] && aLinks[i].template)
                ? aLinks[i].template
                : (wmeJM_Config[i] ? wmeJM_Config[i].template : '');

                // Compute favicon URL: prefer central helper if available, otherwise derive from template (DuckDuckGo)
                let iconURL = '';
                if (typeof WmeJM_GetFaviconURL === 'function') {
                    iconURL = WmeJM_GetFaviconURL(i, template) || '';
                } else {
                    if (typeof template === 'string') {
                        const m = template.match(/https?:\/\/([^\/]+)/);
                        if (m && m[1]) {
                            const domain = m[1].replace(/^www\./, '');
                            iconURL = 'https://icons.duckduckgo.com/ip3/' + encodeURIComponent(domain) + '.ico';
                        }
                    }
                }

                const iconHTML = iconURL ? '<img src="' + iconURL + '" style="width:12px;height:12px;vertical-align:middle;margin-right:4px;">' : '';

                innerHTML += `<a id="${i}" style="color: #fff; font-size: 11px" title="${wmeJM_Config[i].title}">${iconHTML}${wmeJM_Config[i].name}</a>&nbsp;<span style="opacity:0.4;">|</span>&nbsp;`;
            }
        }
    }

    var main_site=location.hostname === "www.waze.com";
    nod.innerHTML =
        (innerHTML || "")
        + "<a id='_map_LI' style='color: #fff; font-size: 10px' title='Open in LiveMap'>[Live]</a>&nbsp;"
        + "<a id='_map_AB' tp="+(main_site?'A':'B')+" href='' style='color: #fff; font-size: 10px' title='Open in "+(main_site?"Beta":"Main")+" editor' target='" +CreateID()+ (main_site?"b":"a")+"' id='__map_BETAALPA'>["+ (main_site?"&#946;":"&#945;")+"]</a>&nbsp;"
        + "<a href='https://greasyfork.org/en/scripts/481079-wme-jumpmaps' title='WME-JumpMaps_" + wmeJM_version + "' style='color: #fff; font-size: 10px' target='_blank'>[?]</a>&nbsp;";

    document.getElementById('waze-map-container').parentElement.appendChild(nod);

    if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_InsertWMEIcon(): innerHTML="+document.getElementById('WME.JumpMaps_' + wmeJM_version).innerHTML);

    for (let i in wmeJM_Config)
    {
        if (document.getElementById(i))
            document.getElementById(i).onclick	= WmeJM_clickJumpToMaps;
    }
    document.getElementById('_map_LI').onclick	= WmeJM_clickJumpToMaps;
    document.getElementById('_map_AB').onclick	= function(){
        var permalink="?"+wmer_generate_permalink().split("?")[1];
        if(wmeJM_debug) console.log("_map_AB.click(), permalink=",permalink);
        if(wmeJM_debug) console.log(this.getAttribute('tp'));
        var main_site=this.getAttribute('tp')==='A';
        this.href=(main_site?"https://beta.waze.com/editor":"https://www.waze.com/editor") + permalink;
        if(wmeJM_debug) console.log(this.href);
    };
}

// Insert button for for jumping to Waze
function WmeJM_InsertIcon()
{
    if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_InsertIcon()");
    var locType=WmeJM_GetLocationType();
    if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_InsertIcon(): locType="+locType);

    if(locType == "waze")
        return true;

    var result = false;

    var nod=document.createElement(locType === "mry" || locType === "osm" || locType === "google"?"div":(locType === "NM"|| locType === "kadua"?"button":"span"));
    nod.setAttribute('id', 'WME.JumpMaps_' + wmeJM_version);
    window.nod=nod;

    var clsid=
        {
            "balticmaps"	  : {t:1,c:"map_mb"},
            "kdlv"	  : {t:1,c:"social_networks"},
        };

    if(typeof clsid[locType] === 'undefined')
    {
        WmeJM_PostLoadOtherMaps();
        return true;
    }

    var WazeControlAttribution = null;
    if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_InsertIcon(): clsid[locType]="+JSON.stringify(clsid[locType]));
    if(clsid[locType])
        WazeControlAttribution = clsid[locType].t == 1?document.getElementById(clsid[locType].c):(clsid[locType].t == 0 || clsid[locType].t == 2?document.getElementsByClassName(clsid[locType].c):document.getElementsByTagName(clsid[locType].c));
    if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_InsertIcon(): WazeControlAttribution="+(typeof WazeControlAttribution),WazeControlAttribution);

    var found00=false;
    if (WazeControlAttribution)
    {
        if (!clsid[locType].t)
        {
            if (WazeControlAttribution.length > 0)
            {
                found00=true;
            }
            else
            {
                if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_InsertIcon(): wait 1 ",locType,clsid[locType]);
                setTimeout(function() {WmeJM_InsertIcon();},500,this);
                return false;
            }
        }
        else
        {
            if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_InsertIcon(): found00=true;");
            found00=true;
        }

        if (!found00)
        {
            if(document.readyState != 'complete' && ++wmeJM_countProbe2 < 5)
            {
                if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_InsertIcon(): wait 2 ",locType,clsid[locType]);
                setTimeout(function() {WmeJM_InsertIcon();},500,this);
                return false;
            }
        }
    }
    else
    {
        if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_InsertIcon(): wait 3 ",clsid[locType]);
        setTimeout(function() {WmeJM_InsertIcon();},100,this);
        return false;
    }

    if (found00)
    {
        if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_InsertIcon(): found '", (clsid[locType].t?WazeControlAttribution:WazeControlAttribution[0]));
        if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_InsertIcon(): document.readyState=" + document.readyState);

        // Note: Since we removed the icon, these cases may need adjustment
        // The icon was previously used in these switch cases
        switch(locType)
        {
            case "balticmaps":
                {
                    nod.setAttribute('style', 'margin-top:11px; margin-right:5px; position:absolute; top:0px; left:558px; z-index:1; border-radius:20px; box-shadow: 0px 1px 8px 0px rgba(0, 0, 0, 0.2), 0px 3px 4px 0px rgba(0, 0, 0, 0.14), 0px 3px 3px -2px rgba(0, 0, 0, 0.12);');
                    nod.innerHTML = "<div id='_map_WME' style='cursor: pointer;' title='Open to WME'><img width=40 height=40 src='"+wmeJM_IconWME+"'></div>";
                    WazeControlAttribution.parentElement.insertBefore(nod, WazeControlAttribution.nextSibling);
                    break;
                }
            case "kdlv":
                {
                    WazeControlAttribution.insertAdjacentHTML('afterbegin', '<a id="_map_WME" class="waze" target="_blank" title="Open in WME"></a>');
                    document.styleSheets[0].insertRule("#social_networks a.waze { background:url("+wmeJM_IconWME+" );background-size: 100% 100%; right: 356px}", 0);
                    break;
                }
        }

        if (document.getElementById('_map_WME'))
        {
            document.getElementById('_map_WME').onclick	 = WmeJM_clickJumpToMaps;
            result=true;
        }
        if (document.getElementById('_map_WMEB'))
        {
            document.getElementById('_map_WMEB').onclick	 = WmeJM_clickJumpToMaps;
            result=true;
        }
    }
    else
    {
        if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_InsertIcon(): ELSE typeof WazeControlAttribution="+(typeof WazeControlAttribution)+", clsid[locType].t="+clsid[locType].t +", WazeControlAttribution.length="+WazeControlAttribution.length+" ["+(WazeControlAttribution && (clsid[locType].t || WazeControlAttribution.length >= 1))+"]");
    }

    if (result)
        WmeJM_PostLoadOtherMaps();

    return result;
}

function createMinimap() {
    if (minimapInstance) return; // Already created
    if (!document.getElementById('leaflet-minimap-css')) {
        const link = document.createElement('link');
        link.id = 'leaflet-minimap-css';
        link.rel = 'stylesheet';
        link.href = 'https://unpkg.com/[email protected]/dist/leaflet.css';
        document.head.appendChild(link);
    }
    const minimapContainer = document.createElement('div');
    minimapContainer.id = 'latvia-minimap';
    minimapContainer.style.cssText = `position: absolute;bottom: 65px;left: 10px;width: 220px;height: 145px;z-index: 1000;border: 1px solid #333;border-radius: 8px;box-shadow: 0 4px 12px rgba(0,0,0,0.3);background: white;overflow: hidden;`;
    const header = document.createElement('div');
    header.style.cssText = `background: #007acc;color: white;font-weight: 400;height: 20px;font-size: 13px;text-align: center;cursor: move;user-select: none;font-family: "Rubik";`;
    function updateLocationHeader() {
        const locationElement = document.querySelector('.location-info');
        if (locationElement && locationElement.textContent) {
            header.textContent = locationElement.textContent;
        }
    }
    setTimeout(updateLocationHeader, 1000);
    setInterval(updateLocationHeader, 2000);
    minimapContainer.appendChild(header);
    const mapDiv = document.createElement('div');
    mapDiv.id = 'minimap-leaflet';
    mapDiv.style.cssText = `width: 100%;height: calc(100% - 20px);`;
    minimapContainer.appendChild(mapDiv);
    document.querySelector('#map').appendChild(minimapContainer);
    makeDraggable(minimapContainer, header);
    minimapInstance = minimapContainer;
    setTimeout(() => {
        const minimap = L.map('minimap-leaflet', {zoomControl: false,attributionControl: false,dragging: false,scrollWheelZoom: false,doubleClickZoom: false,boxZoom: false,keyboard: false,touchZoom: false});
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {maxZoom: 18}).addTo(minimap);
        const latviaBounds = [[55.67, 20.97], [58.09, 28.24]];
        minimap.fitBounds(latviaBounds);
        const viewportMarker = L.circleMarker([56.95, 24.1], {radius: 5,color: '#ffffff',fillColor: '#0099ff',fillOpacity: 0.8,weight: 1}).addTo(minimap);
        function updateViewport() {
            try {
                if (!W.map) return;
                const center = W.map.getCenter();
                if (!center) return;
                const fromProj = new OpenLayers.Projection("EPSG:900913");
                const toProj = new OpenLayers.Projection("EPSG:4326");
                const centerPoint = new OpenLayers.LonLat(center.lon, center.lat).transform(fromProj, toProj);
                viewportMarker.setLatLng([centerPoint.lat, centerPoint.lon]);
            } catch (e) {
                console.error('Error updating viewport:', e);
            }
        }
        W.map.events.register('moveend', null, updateViewport);
        W.map.events.register('zoomend', null, updateViewport);
        updateViewport();
        minimap.on('click', function(e) {
            const latlng = e.latlng;
            const fromProj = new OpenLayers.Projection("EPSG:4326");
            const toProj = new OpenLayers.Projection("EPSG:900913");
            const point = new OpenLayers.LonLat(latlng.lng, latlng.lat).transform(fromProj, toProj);
            W.map.setCenter(point);
        });
    }, 500);
}

function destroyMinimap() {
    if (minimapInstance) {
        minimapInstance.remove();
        minimapInstance = null;
    }
}

function toggleMinimap() {
    if (wmeJM_showMinimap) {
        createMinimap();
    } else {
        destroyMinimap();
    }
}

function makeDraggable(element, handle) {
    let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
    handle.onmousedown = dragMouseDown;
    function dragMouseDown(e) {
        e.preventDefault();
        pos3 = e.clientX;
        pos4 = e.clientY;
        document.onmouseup = closeDragElement;
        document.onmousemove = elementDrag;
    }
    function elementDrag(e) {
        e.preventDefault();
        pos1 = pos3 - e.clientX;
        pos2 = pos4 - e.clientY;
        pos3 = e.clientX;
        pos4 = e.clientY;
        element.style.top = (element.offsetTop - pos2) + "px";
        element.style.left = (element.offsetLeft - pos1) + "px";
        element.style.bottom = 'auto';
        element.style.right = 'auto';
    }
    function closeDragElement() {
        document.onmouseup = null;
        document.onmousemove = null;
    }
}

function WmeJM_onWazeTabReady()
{
    document.getElementById("wmejm_cfg_resetConfig").onclick = function(){
        setTimeout(function() {
            if(confirm("Reset config for WME-JumpMaps?"))
            {
                let d=document.getElementById(CreateID());
                d.parentNode.removeChild(d);
                d=document.getElementById("pwmejumpmaps");
                d.parentNode.removeChild(d);

                localStorage.removeItem("WMEJumpMapsCheckboxStates");
                for(var i in wmeJM_Config)	{ wmeJM_Config[i].save = wmeJM_Config0[i].save; }

                localStorage.removeItem("WMEJumpMapsDebug");
                wmeJM_debug=false;

                WmeJM_InsertWMEIcon();
                WmeJM_InitConfig();
            }
        },100,this);
        return false;
    };

    document.getElementById("wmejm_cfg_debug").onclick = function(){wmeJM_debug=this.checked;localStorage.setItem("WMEJumpMapsDebug",wmeJM_debug?"1":"0");};
    document.getElementById("wmejm_cfg_debug").checked = wmeJM_debug;

    document.getElementById("wmejm_cfg_savedsel").onclick = function(){
        wmeJM_restoreSelected=this.checked;
        localStorage.setItem("WMEJumpMapsRestoreSelected",wmeJM_restoreSelected?"1":"0");
    };
    document.getElementById("wmejm_cfg_savedsel").checked = wmeJM_restoreSelected;

    document.getElementById("wmejm_cfg_window_hide").onclick = function(){
        wmeJM_hideWindow=this.checked;
        localStorage.setItem("WMEJumpMapsHideWindow",wmeJM_hideWindow?"1":"0");
        document.getElementById('WME.JumpMaps_' + wmeJM_version).style.visibility = wmeJM_hideWindow ? "hidden":"visible";
    };
    document.getElementById("wmejm_cfg_window_hide").checked = wmeJM_hideWindow;

    document.getElementById("wmejm_cfg_resetWPos").onclick = function(){
        localStorage.setItem("WMEJumpMapsTopOffset", wmeJM_defaultTopOffset);
        localStorage.setItem("WMEJumpMapsLeftOffset", wmeJM_defaultLeftOffset);

        document.getElementById('WME.JumpMaps_' + wmeJM_version).style.left = wmeJM_defaultLeftOffset;
        document.getElementById('WME.JumpMaps_' + wmeJM_version).style.top = wmeJM_defaultTopOffset;

        wmeJM_topOffset = wmeJM_defaultTopOffset;
        wmeJM_leftOffset = wmeJM_defaultLeftOffset;
    };

    // Load checkbox states
    WmeJM_LoadCheckboxStates();

    for(let i in wmeJM_Config)
    {
        if (["_map_WME","_map_WMEB","_map_LI"].indexOf(i) >= 0)
            continue;

        document.getElementById("wmejm_cfg_"+i).checked = wmeJM_Config[i].save;
        document.getElementById("wmejm_cfg_"+i+"_chklab").innerHTML="&nbsp;"+wmeJM_Config[i].title;

        // Visibility handler - only save checkbox state
        document.getElementById("wmejm_cfg_"+i).onchange = function(){
            var id=this.getAttribute('data');
            wmeJM_Config[id].save = this.checked ? 1 : 0;
            WmeJM_SaveCheckboxStates(); // Save only checkbox states
            WmeJM_InsertWMEIcon();
        };
    }

    // ADD MINIMAP HANDLER HERE:
    document.getElementById("wmejm_cfg_minimap").onclick = function(){
        wmeJM_showMinimap=this.checked;
        localStorage.setItem("WMEJumpMapsShowMinimap",wmeJM_showMinimap?"1":"0");
        toggleMinimap();
    };
    wmeJM_showMinimap = __GetLocalStorageItem("WMEJumpMapsShowMinimap", 'bool', true);
    document.getElementById("wmejm_cfg_minimap").checked = wmeJM_showMinimap;
    if (wmeJM_showMinimap) {
        setTimeout(createMinimap, 1000);
    }
}

function WmeJM_InitConfig()
{
    if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_InitConfig(): "+document.getElementById(CreateID()));
    if(!document.getElementById(CreateID()))
    {
        var srsCtrl = document.createElement('section');
        srsCtrl.id = CreateID();

        var padding="padding:5px 9px";

        // -------------------------------
        var strFormCode = ''
        +'<div class="side-panel-section">'
        +'<h4>WME JumpMaps LV</h4>'
        +'<form class="attributes-form side-panel-section" action="javascript:return false;">'
        +'<div class="form-group">'
        +'<label class="control-label">Map services:</label>'
        +'<div class="controls">';

        // Load checkbox states first
        WmeJM_LoadCheckboxStates();

        for(var i in wmeJM_Config)
        {
            if (["_map_WME","_map_WMEB","_map_LI"].indexOf(i) >= 0)
            {
                continue;
            }
            var id = i;
            var title = wmeJM_Config[id].title;
            var save = wmeJM_Config[id].save;

            // extract base URL from template for hover tooltip
            var baseURL = '';
            if (wmeJM_Config[id].template) {
                var m = wmeJM_Config[id].template.match(/https?:\/\/[^\/]+/);
                if (m) baseURL = m[0];
            }
            // compute favicon for settings panel
            var iconHTML = '';
            var fav = WmeJM_GetFaviconURL(id, wmeJM_Config[id].template);
            if (fav) {
                iconHTML = '<img src="' + fav + '" style="width:16px;height:16px;margin-right:-6px;">';
            }

            strFormCode += ''
                +'<div class="form-group" style="margin-bottom:4px;">'
                +'<div class="control-label" '
                +'style="display:flex; align-items:center; gap:6px; '
                +'font-weight:normal; font-size:14px; line-height:16px;">'
                +'<input data="'+id+'" name="wmejm_cfg_'+id+'" '
                +'id="wmejm_cfg_'+id+'" type="checkbox" ' + (save?'checked':'') + '>'
                + iconHTML
                +'<label id="wmejm_cfg_'+id+'_chklab" for="wmejm_cfg_'+id+'" '
                +'style="cursor:pointer; font-weight:normal; margin:0;" title="' + baseURL + '">'
                + title +
                '</label>'
                +'</div>'
                +'</div>';
        }

        strFormCode += ''
            +'</div>'
            +'</div>';

        // -------------------------------
        strFormCode += ''
            +'<div class="form-group">'
            +'<label class="control-label">Other settings:</label>'
            +'<div class="controls" style="margin:0; line-height:16px;">'
            +'<div style="display:none">'
            +'<input type="checkbox" id="wmejm_cfg_savedsel">'
            +'<label for="wmejm_cfg_savedsel" style="cursor:pointer;margin-left:6px;font-weight:normal;" title="Restore selected">'
            +'<i class="fa fa-clone"></i> Restore selected'
            +'</label><br>'
            +'</div>'
            +'<input type="checkbox" id="wmejm_cfg_minimap">'
            +'<label for="wmejm_cfg_minimap" style="cursor:pointer;margin-left:6px;font-weight:normal;margin-bottom:0px" title="Show minimap">'
            +'<i class="fa fa-map"></i> Show minimap (Latvia)'
            +'</label><br>'
            +'<input type="checkbox" id="wmejm_cfg_debug">'
            +'<label for="wmejm_cfg_debug" style="cursor:pointer;margin-left:6px;font-weight:normal;margin-bottom:0px" title="Debug script">'
            +'<i class="fa fa-bug"></i> Debug script (console logging)'
            +'</label><br>'
            +'<input type="checkbox" id="wmejm_cfg_window_hide">'
            +'<label for="wmejm_cfg_window_hide" style="cursor:pointer;margin-left:6px;font-weight:normal;" title="Hide Window">'
            +'<i class="fa fa-eye-slash"></i> Hide Window'
            +'</label><br>'
            +'<div style="display:none">'
            +'<button id="wmejm_cfg_resetConfig" class="btn btn-default" style="font-size:9px;padding:5px 9px;margin:4px 0;" title="Reset config!">'
            +'<i class="fa fa-recycle"></i> Reset config'
            +'</button><br>'
            +'<button id="wmejm_cfg_resetWPos" class="btn btn-default" style="font-size:9px;padding:5px 9px;" title="Reset window position!">'
            +'<i class="fa fa-recycle"></i> Reset window position'
            +'</button>'
            +'</div>'
            +'</div>'
            +'</div>';

        srsCtrl.className = "tab-pane";
        srsCtrl.innerHTML = strFormCode;
        WazeWrap.Interface.Tab('JumpMaps', strFormCode, WmeJM_onWazeTabReady);
    }
    else
        if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_InitConfig(): not found '"+CreateID()+"'");
}

function WmeJM_FakeLoad()
{
    if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): start WmeJM_FakeLoad(): this"+ this);
    var loctype=WmeJM_GetLocationType();
    if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): start WmeJM_FakeLoad(): loctype="+loctype);

    if(window.document.getElementById('WME.JumpMaps_' + wmeJM_version)) // if THIS is there, then the other checks have passed
    {
        if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_FakeLoad(): FOUND WME.JumpMaps_" + wmeJM_version + "!!!. Done");
        return;
    }

    if (loctype === "waze")
    {
        if (typeof Waze === "undefined")
        {
            if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_FakeLoad(): wait W. Wait 500ms");
            setTimeout(WmeJM_FakeLoad,500);
            return;
        }
        if (typeof W.selectionManager === "undefined")
        {
            if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_FakeLoad(): wait W.selectionManager. Wait 500ms");
            setTimeout(WmeJM_FakeLoad,500);
            return;
        }
        if (document.getElementsByClassName('olControlAttribution')[0] === null)
        {
            if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_FakeLoad(): wait waze olControlAttribution. Wait 500ms");
            setTimeout(WmeJM_FakeLoad,500);
        }
        if (!WazeWrap?.Ready) {
            if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_FakeLoad(): wait WazeWrap. Wait 500ms");
            setTimeout(WmeJM_FakeLoad,500);
            return;
        }
    }

    if (document.readyState != 'complete' && ++wmeJM_countProbe2 < 5)
    {
        if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): WmeJM_FakeLoad(): document.readyState != 'complete', wmeJM_countProbe="+wmeJM_countProbe2+". Wait 3000ms");
        setTimeout(WmeJM_FakeLoad,3000);
        return;
    }

    // Further Initialization
    if (loctype === "waze")
    {
        // What if we jumped from external and if there is a "jmlink" component in the URL, then center the editor at the specified coordinates (EPSG:900913).
        if (__getQueryString(location.href, "jmlink") != -1)
        {
            var jmlink=__getQueryString(location.href, "jmlink").split(",");
            var urPos=new OpenLayers.LonLat(jmlink[1],jmlink[0]);
            urPos.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
            var xy = OpenLayers.Layer.SphericalMercator.forwardMercator(parseFloat(urPos.lon), parseFloat(urPos.lat));
            W.map.setCenter(xy);
        }
        WmeJM_InsertWMEIcon();
        WmeJM_InitConfig();
        WmeJM_initBindKey();
    }
    else
    {
        // Other services...
        if(document.getElementById('WME.JumpMaps_' + wmeJM_version) === null && !WmeJM_InsertIcon())
        {
            if(++wmeJM_countProbe < 8) //  8 attempts
            {
                let cls="";
                if(wmeJM_debug) console.log("WME-JumpMaps (" + wmeJM_version + "): not other found '"+cls+"'. wmeJM_countProbe="+wmeJM_countProbe+". Wait 5000ms");
                setTimeout(WmeJM_FakeLoad,5000);
                return;
            }
        }
        //WmeJM_PostLoadOtherMaps();
    }
}

function __GetLocalStorageItem(Name,Type,Def,Arr)
{
    var tmp0=localStorage.getItem(Name);
    if (tmp0)
    {
        switch(Type)
        {
            case 'string':
                break;
            case 'bool':
                tmp0=(tmp0 === "true" || tmp0 === "1")?true:false;
                break;
            case 'int':
                tmp0=!isNaN(parseInt(tmp0))?parseInt(tmp0):0;
                break;
            case 'arr':
                if (tmp0.length > 0)
                    if(!Arr[tmp0])
                        tmp0=Def;
                break;
        }
    }
    else
        tmp0=Def;
    return tmp0;
}

function WmeJM_clickJumpToMapsArg()
{
    if ((typeof arguments[0]) === "object")
    {
        var o=document.getElementById(arguments[0].id);
        if (typeof o !== "undefined")
        {
            if (arguments[0].save)
                o.click();
        }
    }
}

function WmeJM_initBindKey()
{
    if(wmeJM_debug) console.log("WmeJM_initBindKey()");
    if(!W || !W.model || !I18n || !W.accelerators || !W.model.countries || !W.model.countries.top) {
        setTimeout(WmeJM_initBindKey, 500);
        return;
    }

    var Config =[];

    for(let i in wmeJM_Config)
    {
        Config.push({handler: 'WME-JumpMaps'+i,  title: wmeJM_Config[i].title,  func: WmeJM_clickJumpToMapsArg, key:-1, arg:{id:i,save:wmeJM_Config[i].save}});
    }

    for(let i=0; i < Config.length; ++i)
    {
        // WMEKSRegisterKeyboardShortcut would need to be defined or this function needs adjustment
        // For now, commented out as it's not essential for basic functionality
        // WMEKSRegisterKeyboardShortcut('WME-JumpMaps', 'WME-JumpMaps', Config[i].handler, Config[i].title, Config[i].func, Config[i].key, Config[i].arg);
    }

    // WMEKSLoadKeyboardShortcuts would need to be defined
    // WMEKSLoadKeyboardShortcuts('WME-JumpMaps');

    window.addEventListener("beforeunload", function() {
        // WMEKSSaveKeyboardShortcuts would need to be defined
        // WMEKSSaveKeyboardShortcuts('WME-JumpMaps');
    }, false);
}

// Script launcher
function WmeJM_bootstrap()
{
    console.log("WME-JumpMaps Lite (" + wmeJM_version + "): WmeJM_bootstrap()");

    wmeJM_Config = cloneConfig(wmeJM_Config0);

    wmeJM_debug				= __GetLocalStorageItem("WMEJumpMapsDebug",'bool',false);
    wmeJM_restoreSelected	= __GetLocalStorageItem("WMEJumpMapsRestoreSelected",'bool',false);
    wmeJM_around			= __GetLocalStorageItem("WMEJumpMapsAround",'bool',false);
    wmeJM_hideWindow		= __GetLocalStorageItem("WMEJumpMapsHideWindow",'bool',false);
    wmeJM_topOffset		    = __GetLocalStorageItem("WMEJumpMapsTopOffset",'string', wmeJM_defaultTopOffset);
    wmeJM_leftOffset		= __GetLocalStorageItem("WMEJumpMapsLeftOffset",'string', wmeJM_defaultLeftOffset);

    // Load checkbox states
    WmeJM_LoadCheckboxStates();

    setTimeout(function() {WmeJM_FakeLoad();},(WmeJM_GetLocationType() === "YM")?3000:500,this);
}

WmeJM_bootstrap();