// ==UserScript==
// @name WME Wide-Angle Lens
// @namespace https://greasyfork.org/en/users/19861-vtpearce
// @description Scan a large area
// @author vtpearce and crazycaveman (progress bar from dummyd2 & seb-d59)
// @include https://www.waze.com/editor
// @include /^https:\/\/(www|beta)\.waze\.com\/(?!user\/)(.{2,6}\/)?editor.*$/
// @version 1.4.9.1
// @grant none
// @copyright 2017 vtpearce
// @license CC BY-SA 4.0
// @require https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js
// ==/UserScript==
/*global W, OL, $, WazeWrap*/
var WMEWAL;
(function (WMEWAL) {
const scrName = GM_info.script.name;
const Version = GM_info.script.version;
const updateText = 'Updated library requires updated script<br/><br/><h3>1.4.9</h3><br/><ul><li>When cancelling a scan, properly reset everything even if there are errors</li></ul>';
const greasyForkPage = 'https://greasyfork.org/scripts/40641';
const wazeForumThread = 'https://www.waze.com/forum/viewtopic.php?t=206376';
var ProgressBar = (function () {
function ProgressBar(id) {
this.div = $(id);
}
ProgressBar.prototype.isShown = function () {
return this.div.is(":visible");
};
ProgressBar.prototype.show = function () {
this.div.show();
};
ProgressBar.prototype.hide = function () {
this.div.hide();
};
ProgressBar.prototype.update = function (value) {
logDebug("Percent complete = " + value.toString());
if (value > 100) {
value = 100;
}
if (value === -1) {
this.div.children().hide();
return;
}
this.div.children().show();
this.div.children(".wal-progressBarBG").css("width", value.toString() + "%");
this.div.children(".wal-progressBarFG").text(value.toString() + "%");
};
return ProgressBar;
}());
(function (RoadType) {
RoadType[RoadType["Street"] = 1] = "Street";
RoadType[RoadType["PrimaryStreet"] = 2] = "PrimaryStreet";
RoadType[RoadType["MinorHighway"] = 4] = "MinorHighway";
RoadType[RoadType["MajorHighway"] = 8] = "MajorHighway";
RoadType[RoadType["Freeway"] = 16] = "Freeway";
RoadType[RoadType["Ramp"] = 32] = "Ramp";
RoadType[RoadType["PrivateRoad"] = 64] = "PrivateRoad";
RoadType[RoadType["WalkingTrail"] = 128] = "WalkingTrail";
RoadType[RoadType["Unpaved"] = 256] = "Unpaved";
RoadType[RoadType["PedestrianBoardwalk"] = 512] = "PedestrianBoardwalk";
RoadType[RoadType["Ferry"] = 1024] = "Ferry";
RoadType[RoadType["Stairway"] = 2048] = "Stairway";
RoadType[RoadType["Railroad"] = 4096] = "Railroad";
RoadType[RoadType["RunwayTaxiway"] = 8192] = "RunwayTaxiway";
RoadType[RoadType["ParkingLotRoad"] = 16384] = "ParkingLotRoad";
RoadType[RoadType["Alley"] = 32768] = "Alley";
})(WMEWAL.RoadType || (WMEWAL.RoadType = {}));
var RoadType = WMEWAL.RoadType;
var topLeft = null;
var bottomRight = null;
WMEWAL.areaToScan = null;
var height;
var width;
var segments = null;
var venues = null;
WMEWAL.areaName = null;
var currentX;
var currentY;
var currentCenter = null;
var currentZoom = null;
var layerToggle = null;
var needSegments = false;
var needVenues = false;
var cancelled = false;
var totalViewports;
var countViewports;
var mapReady = false;
var modelReady = false;
var settings = null;
var plugins = [];
var settingsKey = "WMEWAL_Settings";
var debug = false;
var layerName = "WMEWAL_Areas";
var pb = null;
var initCount = 0;
var layerCheckboxAdded = false;
function WideAngleLens() {
console.group("WMEWAL: Initializing");
initCount++;
var objectToCheck = ["W.map",
"W.model.segments",
"W.model.venues",
"W.model.states",
"W.model.events",
"OL",
"W.vent",
"W.controller",
"W.model.actionManager",
"WazeWrap.Interface"];
for (var i = 0; i < objectToCheck.length; i++) {
var path = objectToCheck[i].split(".");
var object = window;
for (var j = 0; j < path.length; j++) {
object = object[path[j]];
if (typeof object === "undefined" || object == null) {
console.warn(path[j] + " NOT OK");
if (initCount < 60) {
console.groupEnd();
window.setTimeout(WideAngleLens, 1000);
}
else {
console.error("Giving up on initialization");
console.groupEnd();
}
return;
}
}
console.log(objectToCheck[i] + " OK");
}
if (typeof (Storage) !== "undefined") {
if (localStorage[settingsKey]) {
var upd = false;
var settingsString = localStorage[settingsKey];
if (settingsString.substring(0, 1) === "~") {
// Compressed value - decompress
//console.log("Decompress UTF16 settings");
settingsString = WMEWAL.LZString.decompressFromUTF16(settingsString.substring(1));
}
try {
settings = JSON.parse(settingsString);
} catch (e) {}
if (typeof settings === "undefined" || settings === null || settings === "") {
settings = "";
console.debug("WMEWAL: Using old decompress method");
localStorage[settingsKey +"Backup"] = localStorage[settingsKey];
settingsString = localStorage[settingsKey];
if (settingsString.substring(0, 1) === "~") {
// Compressed value - decompress
settingsString = WMEWAL.LZString.decompress(settingsString.substring(1));
}
try {
settings = JSON.parse(settingsString);
} catch (e) {}
if (typeof settings === "undefined" || settings === null || settings === "") {
console.warn("WMEWAL: Unable to decompress! Using empty settings");
settings = {
SavedAreas: [],
ActivePlugins: [],
OutputTo: 'csv',
Version: Version
};
}
upd = true;
}
settings.SavedAreas.sort(function (a, b) {
return a.name.localeCompare(b.name);
});
delete settingsString;
if (!settings.hasOwnProperty("Version")) {
settings.Version = Version;
upd = true;
}
for (var ix = 0; ix < settings.SavedAreas.length; ix++) {
if (settings.SavedAreas[ix].geometryText) {
settings.SavedAreas[ix].geometry = OL.Geometry.fromWKT(settings.SavedAreas[ix].geometryText);
while ((settings.SavedAreas[ix].geometry.CLASS_NAME === "OL.Geometry.Collection" ||
settings.SavedAreas[ix].geometry.CLASS_NAME === "OpenLayers.Geometry.Collection") &&
settings.SavedAreas[ix].geometry.components.length === 1) {
settings.SavedAreas[ix].geometry = settings.SavedAreas[ix].geometry.components[0];
upd = true;
}
delete settings.SavedAreas[ix].geometryText;
}
}
if (upd) {
updateSettings();
}
}
else if (localStorage["WMEMSL_areaList"]) {
// Import settings from old MSL script
var savedAreas = JSON.parse(localStorage["WMEMSL_areaList"]);
savedAreas.sort(function (a, b) {
return a.name.localeCompare(b.name);
});
settings = {
SavedAreas: savedAreas,
ActivePlugins: [],
OutputTo: 'csv',
Version: Version
};
for (var ix = 0; ix < settings.SavedAreas.length; ix++) {
if (settings.SavedAreas[ix].geometryText) {
settings.SavedAreas[ix].geometry = OL.Geometry.fromWKT(settings.SavedAreas[ix].geometryText);
delete settings.SavedAreas[ix].geometryText;
}
}
}
else {
settings = {
SavedAreas: [],
ActivePlugins: [],
OutputTo: 'csv',
Version: Version
};
}
}
/*if (CompareVersions(settings.Version, Version) < 0) {
var versionHistory = "WME Wide-Angle Lens\nv" + Version + "\n\nWhat's New\n--------";
if (CompareVersions(settings.Version, "1.4.7") < 0) {
versionHistory += "\nv1.4.7: Choose output on scan tab for all plugins";
}
if (CompareVersions(settings.Version, "1.4.6") < 0) {
versionHistory += "\nv1.4.6: Fixes for the latest release of WME";
}
if (CompareVersions(settings.Version, "1.4.5") < 0) {
versionHistory += "\nv1.4.5: Fixes for the latest release of WME";
}
if (CompareVersions(settings.Version, "1.4.4") < 0) {
versionHistory += "\nv1.4.4: Show tab when changing mode or unit\n"+
" Always hide segments when scanning";
}
if (CompareVersions(settings.Version, "1.4.3.1") < 0) {
versionHistory += "\nv1.4.3.1: Fix for Firefox unable to load settings";
}
if (CompareVersions(settings.Version, "1.4.3") < 0) {
versionHistory += "\nv1.4.3: Add Alley road type and fixes for WME release";
}
if (CompareVersions(settings.Version, "1.4.2") < 0) {
versionHistory += "\nv1.4.2: Fix tab placement";
}
if (CompareVersions(settings.Version, "1.4.1") < 0) {
versionHistory += "\nv1.4.1: Hotfix for 1.4.0";
}
if (CompareVersions(settings.Version, "1.4.0") < 0) {
versionHistory += "\nv1.4.0: Updates to support Firefox.";
}
/*if (CompareVersions(settings.Version, "1.3.4.1") < 0) {
versionHistory += "\nv1.3.4.1: ***BACKUP YOUR AREAS NOW!!***\nThe next version of WAL"+
" could potentially cause data loss.\nSee the forum thread for more info";
}
if (CompareVersions(settings.Version, "1.3.4") < 0) {
versionHistory += "\nv1.3.4: Updates to WME URL";
}
if (CompareVersions(settings.Version, "1.3.3") < 0) {
versionHistory += "\nv1.3.3: Updates to support latest version of WME Editor.";
}
alert(versionHistory);
settings.Version = Version;
updateSettings();
}*/
WazeWrap.Interface.ShowScriptUpdate(scrName, Version, updateText, greasyForkPage, wazeForumThread);
var style = document.createElement("style");
style.type = "text/css";
var css = ".wal-heading { font-size: 1.2em; font-weight: bold }";
css += ".wal-indent { padding-left: 20px }";
css += ".wal-label { margin-left: 8px }";
css += "#wal-progressBarInfo { display: none; width: 90%; float: left; position: absolute; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; margin-bottom: -100%; background-color: #c9e1e9; z-index: 999; margin: 5px; margin-right: 20px; }";
css += ".wal-progressBarBG { margin-top: 2px; margin-bottom: 2px; margin-left: 2px; margin-right: 2px; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; padding-right: 0px; width: 33%; background-color: #93c4d3; border: 3px rgb(147, 196, 211); border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; height: 22px;}";
css += ".wal-progressBarFG { float: left; position: relative; bottom: 22px; height: 0px; text-align: center; width: 100% }";
css += ".wal-textbox { width: 100% }";
style.innerHTML = css;
document.body.appendChild(style);
console.log("Initialized");
console.groupEnd();
makeTab();
//recreate tab here
// Editing mode changed to/from event mode
if (W.app.modeController) {
W.app.modeController.model.bind("change:mode", function (model, modeId) {
if (modeId === 0 && $("#sidepanel-wme-wal").length === 0) {
logDebug("Mode changed");
recreateTab();
}
});
}
// Unit switched (imperial/metric)
if (W.prefs) {
W.prefs.on("change:isImperial", recreateTab);
}
window["WMEWAL"] = WMEWAL;
}
function makeTab() {
var userTabs = $("#user-info");
var navTabs = $("ul.nav-tabs", userTabs).filter(":first");
var tabContent = $(".tab-content", userTabs).filter(":first");
navTabs.append("<li><a href='#sidepanel-wme-wal' data-toggle='tab'>WAL</a></li>");
var addon = $("<div id='sidepanel-wme-wal' class='tab-pane'><h3>Wide-Angle Lens <span style='font-size:11px;'>v"+ Version +"</span></h3></div>");
var pbi = $("<div/>").attr("id", "wal-progressBarInfo").addClass("wal-ProgressBarInfo").appendTo(addon);
var pb$ = $("<div/>").attr("id", "wal-progressBar").css({ width: "100%", display: "none" }).appendTo(pbi);
pb$.append($("<div/>").addClass("wal-progressBarBG"));
pb$.append($("<span/>").addClass("wal-progressBarFG").text("100%"));
pbi.append("<div id='wal-info'/>");
var addonTabs = $("<ul id='wmewal-tabs' class='nav nav-tabs' style='width: 95%;'/>").appendTo(addon);
addonTabs.append("<li class='active'><a data-toggle='tab' href='#sidepanel-wmewal-scan'>Scan</a></li>");
addonTabs.append("<li><a data-toggle='tab' href='#sidepanel-wmewal-areas'>Areas</a></li>");
var addonTabContent = $("<div class='tab-content'/>").appendTo(addon);
var tabScan = $("<div class='tab-pane active' id='sidepanel-wmewal-scan'/>").appendTo(addonTabContent);
tabScan.append("<div><b>Output to: </b><select class='form-control' id='_wmewalScanOutputTo'><option value='csv'>CSV File</option><option value='tab'>Browser Tab</option>" +
"<option value='both'>Both CSV File and Browser Tab</option></select></div><hr/>");
tabScan.append("<div><b>Active Plug-Ins</b><div id='_wmewalPlugins'></div>");
tabScan.append("<div><b>Scan</b><div id='_wmewalOptionsSavedAreas' name='_wmewalSavedAreas'/></div>");
tabScan.append("<hr/>");
var divButtons = $("<div/>").appendTo(tabScan);
divButtons.append("<button class='btn btn-primary' id='_wmewalScan' title='Scan' style='margin-right: 8px'>Scan</button>");
divButtons.append("<button class='btn btn-primary' id='_wmewalCancel' title='Cancel' disabled='disabled'>Cancel</button>");
var tabAreas = $("<div class='tab-pane' id='sidepanel-wmewal-areas'/>").appendTo(addonTabContent);
tabAreas.append("<div id='_wmewalAreasSavedAreas' name='_wmewalSavedAreas'/>");
var divAreaButtons = $("<div/>").appendTo(tabAreas);
divAreaButtons.append("<button class='btn btn-primary' id='_wmewalDeleteArea' title='Delete' style='margin-right: 4px'>Delete</button>");
divAreaButtons.append("<button class='btn btn-primary' id='_wmewalExport' title='Export' style='margin-right: 4px'>Export</button>");
divAreaButtons.append("<button class='btn btn-primary' id='_wmewalRenameArea' title='Rename'>Rename</button>");
tabAreas.append("<div style='margin-top: 12px'><b>Add custom area</b>");
tabAreas.append("<div>From an unsaved area place<div>Name area: <input type='text' id='_wmewalNewAreaName'></div><div>Then <button id='_wmewalAddNewArea' class='btn btn-primary' title='Add'>Add</button></div></div></div>");
var divImportArea = $("<div style='margin-top: 12px'/>").appendTo(tabAreas);
divImportArea.append("<b>Import area</b>");
divImportArea.append("<div><input type='file' id='_wmewalImportFileName' accept='.wkt'/></div><div><button class='btn btn-primary' id='_wmewalImportFile' title='Import'>Import</input></div>");
tabContent.append(addon);
$("#_wmewalScanOutputTo").val(settings.OutputTo || "csv");
updateSavedAreasList();
$("#_wmewalScanOutputTo").on("change", updateSettings);
$("#_wmewalAddNewArea").on("click", addNewArea);
$("#_wmewalCancel").on("click", cancel);
$("#_wmewalScan").on("click", scanArea);
$("#_wmewalExport").on("click", exportArea);
$("#_wmewalRenameArea").on("click", renameArea);
$("#_wmewalDeleteArea").on("click", deleteArea);
$("#_wmewalImportFile").on("click", importFile);
$("#_wmewalPlugins").on("click", function (e) {
$("input[name=_wmewalPlugin]").each(function (ix, item) {
var i = $(item);
var id = i.attr("data-id");
for (var index = 0; index < plugins.length; index++) {
if (plugins[index].Id === parseInt(id)) {
plugins[index].Active = i.prop("checked");
}
}
});
settings.ActivePlugins = [];
for (var ix = 0; ix < plugins.length; ix++) {
if (plugins[ix].Active) {
settings.ActivePlugins.push(plugins[ix].Title);
}
}
updateSettings();
});
}
function recreateTab() {
logDebug("Tab stuff");
makeTab();
plugins.forEach(function(plugin) {
logDebug("Running for plugin: "+plugin.Title);
updatePluginList();
addPluginTab(plugin);
});
}
function info(text) {
text = (typeof text !== "undefined" ? text : "");
$("#wal-info").text(text);
}
function showPBInfo(show) {
if (show) {
$("#wal-progressBarInfo").show();
}
else {
$("#wal-progressBarInfo").hide();
}
}
function addPluginTab(plugin) {
var sidepanel = $("#sidepanel-wme-wal");
var tabs = $("#wmewal-tabs", sidepanel);
tabs.append("<li><a data-toggle='tab' href='#" + plugin.Id + "'>" + plugin.Title + "</a></li>");
var tabContent = $("div.tab-content", sidepanel);
var tab = $("<div class='tab-pane' id='" + plugin.Id + "'/>");
tab.append(plugin.GetTab());
tabContent.append(tab);
if (plugin.TabLoaded) {
plugin.TabLoaded();
}
}
function updatePluginList() {
var list = $("#_wmewalPlugins");
list.empty();
for (var ix = 0; ix < plugins.length; ix++) {
var id = "_wmewalPlugin_" + plugins[ix].Id.toString();
if (ix > 0) {
list.append("<br/>");
}
var c = $("<input type='checkbox' name='_wmewalPlugin'/>")
.attr({ id: id, title: plugins[ix].Title, "data-id": plugins[ix].Id }).appendTo(list);
if (plugins[ix].Active) {
c.attr("checked", "checked");
}
list.append($("<label/>").attr("for", id).css("margin-left", "8px").text(plugins[ix].Title));
}
}
function RegisterPlugIn(plugin) {
var p = plugin;
var found = false;
var r;
do {
r = Math.ceil(Math.random() * 1000);
for (var ix = 0; ix < plugins.length; ix++) {
if (plugins[ix].Id === r) {
found = true;
break;
}
}
} while (found);
p.Id = r;
p.Active = (settings.ActivePlugins.indexOf(plugin.Title) !== -1);
plugins.push(p);
updatePluginList();
addPluginTab(p);
}
WMEWAL.RegisterPlugIn = RegisterPlugIn;
function IsSegmentInArea(segment) {
return WMEWAL.areaToScan.intersects(segment.geometry);
}
WMEWAL.IsSegmentInArea = IsSegmentInArea;
function getVenueGeometry(venue) {
if (venue.isPoint()) {
return venue.getPointGeometry();
}
else {
return venue.getPolygonGeometry();
}
}
function IsVenueInArea(venue) {
return WMEWAL.areaToScan.intersects(getVenueGeometry(venue));
}
WMEWAL.IsVenueInArea = IsVenueInArea;
function getMapCommentGeometry(mapComment) {
if (mapComment.isPoint()) {
return mapComment.getPointGeometry();
}
else {
return mapComment.getPolygonGeometry();
}
}
function IsMapCommentInArea(mapComment) {
return WMEWAL.areaToScan.intersects(getMapCommentGeometry(mapComment));
}
WMEWAL.IsMapCommentInArea = IsMapCommentInArea;
function updateLayer() {
var features = [];
var maLayer = W.map.getLayerByUniqueName(layerName);
if (maLayer === null || typeof maLayer === "undefined") {
maLayer = new OL.Layer.Vector("Wide-Angle Lens Areas", {
uniqueName: layerName
});
I18n.translations[I18n.currentLocale()].layers.name[layerName] = "Wide-Angle Lens Areas";
W.map.addUniqueLayer(maLayer);
maLayer.setVisibility(false);
}
maLayer.removeAllFeatures({
silent: true
});
for (var ixA = 0; ixA < settings.SavedAreas.length; ixA++) {
var style = {
strokeColor: "#FF6600",
strokeOpacity: 0.8,
strokeWidth: 3,
fillOpacity: 0.00,
label: settings.SavedAreas[ixA].name,
labelOutlineColor: "Black",
labelOutlineWidth: 3,
fontSize: 14,
fontColor: "#FF6600",
fontOpacity: 0.85,
fontWeight: "bold"
};
features.push(new OL.Feature.Vector(settings.SavedAreas[ixA].geometry.clone(), {
areaName: settings.SavedAreas[ixA].name
}, style));
}
maLayer.addFeatures(features);
if (!layerCheckboxAdded) {
WazeWrap.Interface.AddLayerCheckbox("display", "Wide-Angle Lens Areas", false, function (checked) {
maLayer.setVisibility(checked);
});
layerCheckboxAdded = true;
}
}
// function addLatLonArray(latLonArray, arrayName): void
// {
// let points: Array<OL.Geometry> = [];
// for (let i = 0; i < latLonArray.length; i++)
// {
// points.push(new OL.Geometry.Point(latLonArray[i].lon, latLonArray[i].lat).transform(new OL.Projection("EPSG:4326"), W.map.getProjectionObject()));
// }
// let ring = new OL.Geometry.LinearRing(points);
// let polygon = new OL.Geometry.Polygon([ring]);
// savedAreas.push({name: arrayName, geometry: polygon});
// }
function addNewArea() {
var theVenue = null;
var count = 0;
for (var v in W.model.venues.objects) {
if (W.model.venues.objects.hasOwnProperty(v) === false) {
continue;
}
var venue = W.model.venues.objects[v];
if (venue.isPoint() === true) {
continue;
}
if ($.isNumeric(venue.attributes.id) && parseInt(venue.attributes.id) <= 0) {
theVenue = venue;
count++;
}
}
if (count > 1) {
alert("There must be only one unsaved area place.\n" + count + " detected.\nDraw only one area place to scan.");
return;
}
if (count === 0) {
alert("You must drawn an area place and not save it.");
return;
}
if (theVenue.geometry.components.length !== 1) {
alert("Can't parse the geometry");
return;
}
var nameBox = $("#_wmewalNewAreaName")[0];
if (nameBox.value.trim().length === 0) {
alert("Please provide a name for the new area.");
return;
}
var savedArea = {
name: nameBox.value.trim(),
geometry: theVenue.geometry.clone()
};
settings.SavedAreas.push(savedArea);
updateSavedAreasList();
if (W.model.actionManager.canUndo()) {
if (confirm("Undo all edits (OK=Yes, Cancel=No)?")) {
/* tslint:disable:no-empty */
while (W.model.actionManager.undo()) {
}
}
}
return;
}
function removeSavedArea(index) {
if (index >= settings.SavedAreas.length) {
return;
}
if (confirm("Removed saved area?")) {
settings.SavedAreas.splice(index, 1);
updateSavedAreasList();
}
}
function updateSavedAreasList() {
function getCenterFunc(index) {
return function () {
var center = settings.SavedAreas[index].geometry.getCentroid();
var lonlat = new OL.LonLat(center.x, center.y);
W.map.setCenter(lonlat);
};
}
settings.SavedAreas.sort(function (a, b) {
return a.name.localeCompare(b.name);
});
var list = $("div[name=_wmewalSavedAreas]");
list.empty();
list.each(function (eIx, e) {
for (var ix = 0; ix < settings.SavedAreas.length; ix++) {
var id = "_wmewalScanArea_" + eIx.toString() + "_" + ix.toString();
var input = $("<input/>").attr({ type: "radio", name: "_wmewalScanArea", id: id, value: ix.toString() });
e.appendChild(input[0]);
var label = $("<label/>").attr("for", id).css("margin-left", "8px").text(settings.SavedAreas[ix].name);
e.appendChild(label[0]);
var center = $("<i/>").addClass("fa").addClass("fa-crosshairs").css("margin-left", "4px").on("click", getCenterFunc(ix));
e.appendChild(center[0]);
// var div = document.createElement('div');
// var link = document.createElement('a');
// link.href = '#';
// link.onclick = (function (index) {
// return function() {
// scanArea(index);
// };
// })(ix);
// link.text = savedAreas[ix].name;
// div.appendChild(link);
// e.appendChild(document.createTextNode("\u00A0"));
// e.appendChild(delLink);
var br = $("<br/>");
e.appendChild(br[0]);
}
});
updateSettings();
updateLayer();
}
function updateSettings() {
if (typeof Storage !== "undefined") {
var newSettings = {
SavedAreas: [],
ActivePlugins: settings.ActivePlugins,
OutputTo: $("#_wmewalScanOutputTo").val(),
Version: settings.Version
};
for (var ix = 0; ix < settings.SavedAreas.length; ix++) {
newSettings.SavedAreas.push({
name: settings.SavedAreas[ix].name,
geometryText: settings.SavedAreas[ix].geometry.toString()
});
}
localStorage[settingsKey] = "~" + WMEWAL.LZString.compressToUTF16(JSON.stringify(newSettings));
}
}
function importFile() {
var input = $("#_wmewalImportFileName")[0];
if (input.files.length === 0) {
alert("Select a file to import.");
return;
}
var fileName = input.files[0].name;
var fileExt = fileName.split(".").pop();
var name = fileName.replace("." + fileExt, "");
var reader = new FileReader();
reader.onload = function (e) {
var parser = new OL.Format.WKT();
var features = parser.read(e.target.result);
var feature;
while (features instanceof Array && features.length === 1) {
features = features[0];
}
if (features instanceof OL.Feature.Vector) {
feature = features;
}
else {
alert("Could not parse geometry.");
return;
}
// Assume geometry is in EPSG:4326 and reproject to Spherical Mercator
var fromProj = new OL.Projection("EPSG:4326");
var c = feature.geometry.clone();
c.transform(fromProj, W.map.getProjectionObject());
var savedArea = {
name: name,
geometry: c
};
settings.SavedAreas.push(savedArea);
updateSavedAreasList();
};
reader.readAsText(input.files[0]);
}
function getBounds() {
if (WMEWAL.areaToScan == null) {
return;
}
WMEWAL.areaToScan.calculateBounds();
var bounds = WMEWAL.areaToScan.getBounds();
topLeft = new OL.Geometry.Point(bounds.left, bounds.top);
bottomRight = new OL.Geometry.Point(bounds.right, bounds.bottom);
}
function scanExtent() {
if (cancelled) {
return;
}
logDebug("Scan Extent");
var extentSegments = [];
var extentVenues = [];
// Check to see if the current extent is completely within the area being searched
// let allIn = true;
// let vertices = W.map.getExtent().toGeometry().getVertices();
// for (let ix = 0; ix < vertices.length && allIn; ix++) {
// allIn = allIn && geoCollection.intersects(vertices[ix]);
// }
// logDebug("Extent is " + (!allIn ? "NOT " : "") + "entirely within area");
if (needSegments && segments != null) {
logDebug("Collecting segments");
for (var seg in W.model.segments.objects) {
if (segments.indexOf(seg) === -1) {
var segment = W.model.segments.getObjectById(parseInt(seg));
if (segment != null) {
segments.push(seg);
extentSegments.push(segment);
}
}
}
logDebug("Done collecting segments");
}
if (needVenues && venues != null) {
logDebug("Collecting venues");
for (var ven in W.model.venues.objects) {
if (venues.indexOf(ven) === -1) {
var venue = W.model.venues.getObjectById(ven);
if (venue != null) {
venues.push(ven);
extentVenues.push(venue);
}
}
}
logDebug("Done collecting venues");
}
var promises = [];
for (var ix = 0; ix < plugins.length; ix++) {
if (plugins[ix].Active) {
logDebug("Calling plugin " + plugins[ix].Title);
if (!cancelled) {
promises.push(plugins[ix].ScanExtent(extentSegments, extentVenues));
}
}
}
if (promises.length > 0) {
$.when(promises);
}
logDebug("Finished scanning extent");
}
function moveToNextLocation() {
logDebug("Move To Next Location");
var done = false;
var inGeometry = false;
do {
if (WMEWAL.areaToScan == null) {
done = true;
}
else {
countViewports += 1;
logDebug("Count viewports = " + countViewports.toString());
currentX += width;
if (currentX > bottomRight.x + width) {
logDebug("New row");
// Start at next row
currentX = topLeft.x;
currentY -= height;
if (currentY < bottomRight.y - height) {
done = true;
}
}
if (!done) {
// Check to see if the new window would be within the boundaries of the original area
// Create a geometry object for the window boundaries
var points = [];
points.push(new OL.Geometry.Point(currentX - (width / 2), currentY + (height / 2)));
points.push(new OL.Geometry.Point(currentX + (width / 2), currentY + (height / 2)));
points.push(new OL.Geometry.Point(currentX - (width / 2), currentY - (height / 2)));
points.push(new OL.Geometry.Point(currentX + (width / 2), currentY - (height / 2)));
var lr = new OL.Geometry.LinearRing(points);
var poly = new OL.Geometry.Polygon([lr]);
inGeometry = WMEWAL.areaToScan && WMEWAL.areaToScan.intersects(poly);
}
}
if (!inGeometry) {
var progress = Math.floor(countViewports / totalViewports * 100);
pb.update(progress);
}
} while (!inGeometry && !done);
if (done) {
processComplete();
}
else {
onModelReady(onOperationDone, false, null);
logDebug("Moving map");
W.map.setCenter(new OL.LonLat(currentX, currentY));
}
}
function onOperationDone(e) {
if (!cancelled) {
scanExtent();
var progress = Math.floor(countViewports / totalViewports * 100);
pb.update(progress);
moveToNextLocation();
}
}
function onModelReady(callback, now, context) {
var deferModelReady;
var deferMapReady;
function modelReadyResolve() {
logDebug("mergeend, unregistering");
W.model.events.unregister("mergeend", null, modelReadyResolve);
deferModelReady.resolve();
}
function mapReadyResolve(e) {
if (e.operation.id === "pending.road_data") {
logDebug("operationDone, unregistering");
W.vent.off("operationDone", mapReadyResolve);
deferMapReady.resolve();
}
}
logDebug("On Model Ready");
if (typeof callback === "function") {
context = context || callback;
if (now && mapReady && modelReady) {
callback.call(context);
}
else {
deferModelReady = $.Deferred();
logDebug("Registering for mergeend");
W.model.events.register("mergeend", null, modelReadyResolve);
// function (dfd) {
// let resolve = function () {
// logDebug("mergeend, unregistering");
// W.model.events.unregister("mergeend", null, resolve);
// dfd.resolve();
// };
// logDebug("Registering for mergeend");
// W.model.events.register("mergeend", null, resolve);
// });
deferMapReady = $.Deferred();
logDebug("Registering for operationDone");
W.vent.on("operationDone", mapReadyResolve);
// function (dfd) {
// let resolve = function (e) {
// if (e.operation.id === "pending.road_data") {
// logDebug("operationDone, unregistering");
// W.vent.off("operationDone", resolve);
// dfd.resolve();
// }
// };
// logDebug("Registing for operationDone");
// W.vent.on("operationDone", resolve);
// });
var timerSet_1 = true;
var timer_1 = setTimeout(function () {
timerSet_1 = false;
// Wait a max of 10 seconds to move the map. If it hasn't happened by then, it won't happen
logDebug("Timeout");
mapReadyResolve({ operation: { id: "pending.road_data" } });
modelReadyResolve();
}, 10000);
$.when(deferMapReady, deferModelReady).
then(function () {
if (timerSet_1) {
clearTimeout(timer_1);
timerSet_1 = false;
}
logDebug("Map and Model are ready");
callback.call(context);
});
}
}
}
function cancel() {
cancelled = true;
for (var ix = 0; ix < plugins.length; ix++) {
if (plugins[ix].Active && plugins[ix].ScanCancelled) {
try {
plugins[ix].ScanCancelled();
} catch (e) {
console.warn(`WMEWAL: Trouble cancelling plugin ${plugins[ix].Title}\n${e.message}`);
}
}
}
resetState();
}
function processComplete() {
pb.update(100);
logDebug("Process Complete");
for (var ix = 0; ix < plugins.length; ix++) {
if (plugins[ix].Active && plugins[ix].ScanComplete) {
plugins[ix].ScanComplete();
}
}
resetState();
}
function alertBeforeClose(e) {
if (WMEWAL.areaToScan !== null) {
logDebug('Alerting user before closing page');
e.preventDefault();
e.returnValue = 'Scan running. Cancel and leave the page?';
return e.returnValue;
}
else {
return false;
}
};
function resetState() {
pb.hide();
showPBInfo(false);
info("");
logDebug("Reset state");
WMEWAL.areaToScan = null;
// Return to previous state
if (layerToggle != null) {
while (layerToggle.length > 0) {
var ln = layerToggle.pop();
$("#" + ln).trigger("click");
}
layerToggle = null;
}
if (currentCenter != null) {
logDebug("Moving back to original location");
W.map.setCenter(currentCenter);
}
if (currentZoom != null) {
logDebug("Resetting zoom");
W.map.zoomTo(currentZoom);
}
segments = null;
venues = null;
$("#_wmewalCancel").attr("disabled", "disabled");
// Remove listeners for unloading page
window.removeEventListener('beforeunload', alertBeforeClose);
window.removeEventListener('unload', cancel);
}
function exportArea() {
var index = -1;
var nodes = $("input[name=_wmewalScanArea]", "#_wmewalAreasSavedAreas");
for (var ix = 0; ix < nodes.length; ix++) {
if (nodes[ix].checked) {
index = ix;
break;
}
}
if (index === -1) {
alert("Please select an area to export.");
return;
}
else if (index >= settings.SavedAreas.length) {
return;
}
var c = new OL.Geometry.Collection([settings.SavedAreas[index].geometry.clone()]);
// Transform the collection to EPSG:4326
var toProj = new OL.Projection("EPSG:4326");
c.transform(W.map.getProjectionObject(), toProj);
var geoText = c.toString();
var encodedUri = "data:text/plain;charset=utf-8," + encodeURIComponent(geoText);
var link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", settings.SavedAreas[index].name + ".wkt");
var node = document.body.appendChild(link);
link.click();
document.body.removeChild(node);
}
function deleteArea() {
var index = -1;
var nodes = $("input[name=_wmewalScanArea]", "#_wmewalAreasSavedAreas");
for (var ix = 0; ix < nodes.length; ix++) {
if (nodes[ix].checked) {
index = ix;
break;
}
}
if (index === -1) {
alert("Please select an area to delete.");
return;
}
else if (index >= settings.SavedAreas.length) {
return;
}
removeSavedArea(index);
}
function renameArea() {
var index = -1;
var nodes = $("input[name=_wmewalScanArea]", "#_wmewalAreasSavedAreas");
for (var ix = 0; ix < nodes.length; ix++) {
if (nodes[ix].checked) {
index = ix;
break;
}
}
if (index === -1) {
alert("Please select an area to rename.");
return;
}
else if (index >= settings.SavedAreas.length) {
return;
}
var newName = prompt("Enter a new name");
if (newName == null) {
return;
}
settings.SavedAreas[index].name = newName;
updateSavedAreasList();
}
function scanArea() {
var index = -1;
var nodes = $("input[name=_wmewalScanArea]", "#_wmewalOptionsSavedAreas");
for (var ix = 0; ix < nodes.length; ix++) {
if (nodes[ix].checked) {
index = ix;
break;
}
}
if (index === -1) {
alert("Please select an area to scan.");
return;
}
else if (index >= settings.SavedAreas.length) {
return;
}
WMEWAL.areaToScan = settings.SavedAreas[index].geometry;
scan(settings.SavedAreas[index].name);
}
function scan(name) {
getBounds();
if (topLeft == null || bottomRight == null) {
alert("No bounds");
return;
}
var anyActivePlugins = false;
needSegments = false;
needVenues = false;
var needMapComments = false;
for (var ix = 0; ix < plugins.length; ix++) {
if (plugins[ix].Active) {
anyActivePlugins = true;
needSegments = needSegments || plugins[ix].SupportsSegments;
needVenues = needVenues || plugins[ix].SupportsVenues;
if (plugins[ix].Title === "Map Comments") {
needMapComments = true;
}
}
}
if (!anyActivePlugins) {
alert("Please make sure at least one plug-in is active.");
return;
}
WMEWAL.areaName = name;
segments = [];
venues = [];
var allOk = true;
pb = new ProgressBar("#wal-progressBar");
pb.update(0);
pb.show();
showPBInfo(true);
for (var ix = 0; ix < plugins.length; ix++) {
if (plugins[ix].Active) {
info("Initializing plugin " + plugins[ix].Title);
allOk = allOk && plugins[ix].ScanStarted();
}
}
info("");
if (!allOk) {
pb.hide();
showPBInfo(false);
return;
}
info("Please don't touch anything during the scan");
$("#_wmewalCancel").removeAttr("disabled");
// Alert user if they try to leave the page before scan is finished
window.addEventListener('beforeunload', alertBeforeClose);
//Cleanup when closing page
window.addEventListener('unload', cancel);
// Save current state
currentCenter = W.map.getCenter();
currentZoom = W.map.zoom;
layerToggle = [];
var groups = $("div.layer-switcher li.group");
groups.each(function (ix, g) {
var groupToggle = $(g).children("div.toggler").find("input[type=checkbox]");
switch ($(groupToggle).attr("id")) {
case "layer-switcher-group_places":
if (needVenues) {
if (!$(groupToggle).prop("checked")) {
$(groupToggle).trigger("click");
layerToggle.push($(groupToggle).attr("id"));
}
// Loop through each child in the group
$(g).find("ul.children > li > div.toggler input[type=checkbox]").each(function (ixChild, c) {
switch ($(c).attr("id")) {
case "layer-switcher-item_venues":
case "layer-switcher-item_residential_places":
case "layer-switcher-item_parking_places":
if (!$(c).prop("checked")) {
$(c).trigger("click");
layerToggle.push($(c).attr("id"));
}
break;
default:
if ($(c).prop("checked")) {
$(c).trigger("click");
layerToggle.push($(c).attr("id"));
}
break;
}
});
}
else {
if ($(groupToggle).prop("checked")) {
$(groupToggle).trigger("click");
layerToggle.push($(groupToggle).attr("id"));
}
}
break;
case "layer-switcher-group_road":
if ($(groupToggle).prop("checked")) {
$(groupToggle).trigger("click");
layerToggle.push($(groupToggle).attr("id"));
}
break;
case "layer-switcher-group_display":
if (needMapComments) {
if (!$(groupToggle).prop("checked")) {
$(groupToggle).trigger("click");
layerToggle.push($(groupToggle).attr("id"));
}
// Loop through each child in the group
$(g).find("ul.children > li > div.toggler input[type=checkbox]").each(function (ixChild, c) {
switch ($(c).attr("id")) {
case "layer-switcher-item_map_comments":
if (!$(c).prop("checked")) {
$(c).trigger("click");
layerToggle.push($(c).attr("id"));
}
break;
default:
if ($(c).prop("checked")) {
$(c).trigger("click");
layerToggle.push($(c).attr("id"));
}
break;
}
});
}
else {
if ($(groupToggle).prop("checked")) {
$(groupToggle).trigger("click");
layerToggle.push($(groupToggle).attr("id"));
}
}
break;
default:
if ($(groupToggle).prop("checked")) {
$(groupToggle).trigger("click");
layerToggle.push($(groupToggle).attr("id"));
}
break;
}
});
// Reload road layers
if (!W.model.actionManager.canUndo()) {
for (var ix = 0; ix < W.map.roadLayers.length; ix++) {
W.map.roadLayers[ix].redraw(true);
}
W.controller.reload();
}
var minZoomLevel = 1;
for (var ix = 0; ix < plugins.length; ix++) {
if (plugins[ix].Active) {
if (plugins[ix].MinimumZoomLevel > minZoomLevel) {
minZoomLevel = plugins[ix].MinimumZoomLevel;
}
}
}
WMEWAL.zoomLevel = minZoomLevel;
W.map.zoomTo(WMEWAL.zoomLevel);
var extent = W.map.getExtent();
height = extent.getHeight();
width = extent.getWidth();
// Figure out how many horizontal and vertical viewports there are
var horizontalSpan = Math.floor((bottomRight.x - topLeft.x) / width) + 2;
var verticalSpan = Math.floor((topLeft.y - bottomRight.y) / height) + 2;
totalViewports = horizontalSpan * verticalSpan + 1;
countViewports = 0;
logDebug("Horizontal span = " + horizontalSpan.toString());
logDebug("Vertical span = " + verticalSpan.toString());
logDebug("Total viewports = " + totalViewports.toString());
currentX = topLeft.x - width;
currentY = topLeft.y;
pb.show();
cancelled = false;
moveToNextLocation();
}
function logDebug(message) {
if (debug) {
var t = new Date();
var timeString = t.getHours().toString() + ":" + t.getMinutes().toString() + ":" +
t.getSeconds().toString() + ":" + t.getMilliseconds().toString();
console.log("WMEWAL " + timeString + ": " + message);
}
}
function WazeRoadTypeToRoadTypeBitmask(roadType) {
switch (roadType) {
case 1:
return RoadType.Street;
case 2:
return RoadType.PrimaryStreet;
case 3:
return RoadType.Freeway;
case 4:
return RoadType.Ramp;
case 5:
return RoadType.WalkingTrail;
case 6:
return RoadType.MajorHighway;
case 7:
return RoadType.MinorHighway;
case 8:
return RoadType.Unpaved;
case 10:
return RoadType.PedestrianBoardwalk;
case 15:
return RoadType.Ferry;
case 16:
return RoadType.Stairway;
case 17:
return RoadType.PrivateRoad;
case 18:
return RoadType.Railroad;
case 19:
return RoadType.RunwayTaxiway;
case 20:
return RoadType.ParkingLotRoad;
case 22:
return RoadType.Alley;
default:
return 0;
}
}
WMEWAL.WazeRoadTypeToRoadTypeBitmask = WazeRoadTypeToRoadTypeBitmask;
function RoadTypeBitmaskToWazeRoadType(roadType) {
switch (roadType) {
case RoadType.Street:
return 1;
case RoadType.PrimaryStreet:
return 2;
case RoadType.Freeway:
return 3;
case RoadType.Ramp:
return 4;
case RoadType.WalkingTrail:
return 5;
case RoadType.MajorHighway:
return 6;
case RoadType.MinorHighway:
return 7;
case RoadType.Unpaved:
return 8;
case RoadType.PedestrianBoardwalk:
return 10;
case RoadType.Ferry:
return 15;
case RoadType.Stairway:
return 16;
case RoadType.PrivateRoad:
return 17;
case RoadType.Railroad:
return 18;
case RoadType.RunwayTaxiway:
return 19;
case RoadType.ParkingLotRoad:
return 20;
case RoadType.Alley:
return 22;
default:
return 0;
}
}
WMEWAL.RoadTypeBitmaskToWazeRoadType = RoadTypeBitmaskToWazeRoadType;
function TranslateRoadType(wazeRoadType) {
return I18n.t("segment.road_types." + wazeRoadType.toString());
}
WMEWAL.TranslateRoadType = TranslateRoadType;
function GenerateBasePL(lat, lon, zoom) {
return "https://www.waze.com/editor/?env=" + W.app.getAppRegionCode() + "&lon=" + lon + "&lat=" + lat + "&zoom=" + zoom;
}
WMEWAL.GenerateBasePL = GenerateBasePL;
function CompareVersions(v1, v2) {
var v1Parts = v1.split(".");
var v2Parts = v2.split(".");
for (; v1Parts.length < v2Parts.length;) {
v1Parts.push(".0");
}
for (; v2Parts.length < v1Parts.length;) {
v2Parts.push(".0");
}
for (var ix = 0; ix < v1Parts.length; ix++) {
var v1Element = parseInt(v1Parts[ix]);
var v2Element = parseInt(v2Parts[ix]);
if (v1Element < v2Element) {
return -1;
}
else if (v1Element > v2Element) {
return 1;
}
}
return 0;
}
WMEWAL.CompareVersions = CompareVersions;
// Copyright (c) 2013 Pieroxy <[email protected]>
// This work is free. You can redistribute it and/or modify it
// under the terms of the WTFPL, Version 2
// For more information see LICENSE.txt or http://www.wtfpl.net/
//
// For more information, the home page:
// http://pieroxy.net/blog/pages/lz-string/testing.html
//
// LZ-based compression algorithm, version 1.4.4
/* tslint:disable */
WMEWAL.LZString = (function () {
// private property
var f = String.fromCharCode;
var keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$";
var baseReverseDic = {};
function getBaseValue(alphabet, character) {
if (!baseReverseDic[alphabet]) {
baseReverseDic[alphabet] = {};
for (var i = 0; i < alphabet.length; i++) {
baseReverseDic[alphabet][alphabet.charAt(i)] = i;
}
}
return baseReverseDic[alphabet][character];
}
var LZString = {
compressToBase64: function (input) {
if (input == null)
return "";
var res = LZString._compress(input, 6, function (a) { return keyStrBase64.charAt(a); });
switch (res.length % 4) {
default: // When could this happen ?
case 0: return res;
case 1: return res + "===";
case 2: return res + "==";
case 3: return res + "=";
}
},
decompressFromBase64: function (input) {
if (input == null)
return "";
if (input == "")
return null;
return LZString._decompress(input.length, 32, function (index) { return getBaseValue(keyStrBase64, input.charAt(index)); });
},
compressToUTF16: function (input) {
if (input == null)
return "";
return LZString._compress(input, 15, function (a) { return f(a + 32); }) + " ";
},
decompressFromUTF16: function (compressed) {
if (compressed == null)
return "";
if (compressed == "")
return null;
return LZString._decompress(compressed.length, 16384, function (index) { return compressed.charCodeAt(index) - 32; });
},
//compress into uint8array (UCS-2 big endian format)
compressToUint8Array: function (uncompressed) {
var compressed = LZString.compress(uncompressed);
var buf = new Uint8Array(compressed.length * 2); // 2 bytes per character
for (var i = 0, TotalLen = compressed.length; i < TotalLen; i++) {
var current_value = compressed.charCodeAt(i);
buf[i * 2] = current_value >>> 8;
buf[i * 2 + 1] = current_value % 256;
}
return buf;
},
//decompress from uint8array (UCS-2 big endian format)
decompressFromUint8Array: function (compressed) {
if (compressed == null || compressed === undefined) {
return LZString.decompress(compressed);
}
else {
var buf = new Array(compressed.length / 2); // 2 bytes per character
for (var i = 0, TotalLen = buf.length; i < TotalLen; i++) {
buf[i] = compressed[i * 2] * 256 + compressed[i * 2 + 1];
}
var result_1 = [];
buf.forEach(function (c) {
result_1.push(f(c));
});
return LZString.decompress(result_1.join(''));
}
},
//compress into a string that is already URI encoded
compressToEncodedURIComponent: function (input) {
if (input == null)
return "";
return LZString._compress(input, 6, function (a) { return keyStrUriSafe.charAt(a); });
},
//decompress from an output of compressToEncodedURIComponent
decompressFromEncodedURIComponent: function (input) {
if (input == null)
return "";
if (input == "")
return null;
input = input.replace(/ /g, "+");
return LZString._decompress(input.length, 32, function (index) { return getBaseValue(keyStrUriSafe, input.charAt(index)); });
},
compress: function (uncompressed) {
return LZString._compress(uncompressed, 16, function (a) { return f(a); });
},
_compress: function (uncompressed, bitsPerChar, getCharFromInt) {
if (uncompressed == null)
return "";
var i, value, context_dictionary = {}, context_dictionaryToCreate = {}, context_c = "", context_wc = "", context_w = "", context_enlargeIn = 2, // Compensate for the first entry which should not count
context_dictSize = 3, context_numBits = 2, context_data = [], context_data_val = 0, context_data_position = 0, ii;
for (var ii_1 = 0; ii_1 < uncompressed.length; ii_1 += 1) {
context_c = uncompressed.charAt(ii_1);
if (!Object.prototype.hasOwnProperty.call(context_dictionary, context_c)) {
context_dictionary[context_c] = context_dictSize++;
context_dictionaryToCreate[context_c] = true;
}
context_wc = context_w + context_c;
if (Object.prototype.hasOwnProperty.call(context_dictionary, context_wc)) {
context_w = context_wc;
}
else {
if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
if (context_w.charCodeAt(0) < 256) {
for (var i_1 = 0; i_1 < context_numBits; i_1++) {
context_data_val = (context_data_val << 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.push(getCharFromInt(context_data_val));
context_data_val = 0;
}
else {
context_data_position++;
}
}
value = context_w.charCodeAt(0);
for (var i_2 = 0; i_2 < 8; i_2++) {
context_data_val = (context_data_val << 1) | (value & 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.push(getCharFromInt(context_data_val));
context_data_val = 0;
}
else {
context_data_position++;
}
value = value >> 1;
}
}
else {
value = 1;
for (var i_3 = 0; i_3 < context_numBits; i_3++) {
context_data_val = (context_data_val << 1) | value;
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.push(getCharFromInt(context_data_val));
context_data_val = 0;
}
else {
context_data_position++;
}
value = 0;
}
value = context_w.charCodeAt(0);
for (var i_4 = 0; i_4 < 16; i_4++) {
context_data_val = (context_data_val << 1) | (value & 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.push(getCharFromInt(context_data_val));
context_data_val = 0;
}
else {
context_data_position++;
}
value = value >> 1;
}
}
context_enlargeIn--;
if (context_enlargeIn == 0) {
context_enlargeIn = Math.pow(2, context_numBits);
context_numBits++;
}
delete context_dictionaryToCreate[context_w];
}
else {
value = context_dictionary[context_w];
for (var i_5 = 0; i_5 < context_numBits; i_5++) {
context_data_val = (context_data_val << 1) | (value & 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.push(getCharFromInt(context_data_val));
context_data_val = 0;
}
else {
context_data_position++;
}
value = value >> 1;
}
}
context_enlargeIn--;
if (context_enlargeIn == 0) {
context_enlargeIn = Math.pow(2, context_numBits);
context_numBits++;
}
// Add wc to the dictionary.
context_dictionary[context_wc] = context_dictSize++;
context_w = String(context_c);
}
}
// Output the code for w.
if (context_w !== "") {
if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
if (context_w.charCodeAt(0) < 256) {
for (var i_6 = 0; i_6 < context_numBits; i_6++) {
context_data_val = (context_data_val << 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.push(getCharFromInt(context_data_val));
context_data_val = 0;
}
else {
context_data_position++;
}
}
value = context_w.charCodeAt(0);
for (var i_7 = 0; i_7 < 8; i_7++) {
context_data_val = (context_data_val << 1) | (value & 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.push(getCharFromInt(context_data_val));
context_data_val = 0;
}
else {
context_data_position++;
}
value = value >> 1;
}
}
else {
value = 1;
for (var i_8 = 0; i_8 < context_numBits; i_8++) {
context_data_val = (context_data_val << 1) | value;
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.push(getCharFromInt(context_data_val));
context_data_val = 0;
}
else {
context_data_position++;
}
value = 0;
}
value = context_w.charCodeAt(0);
for (var i_9 = 0; i_9 < 16; i_9++) {
context_data_val = (context_data_val << 1) | (value & 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.push(getCharFromInt(context_data_val));
context_data_val = 0;
}
else {
context_data_position++;
}
value = value >> 1;
}
}
context_enlargeIn--;
if (context_enlargeIn == 0) {
context_enlargeIn = Math.pow(2, context_numBits);
context_numBits++;
}
delete context_dictionaryToCreate[context_w];
}
else {
value = context_dictionary[context_w];
for (var i_10 = 0; i_10 < context_numBits; i_10++) {
context_data_val = (context_data_val << 1) | (value & 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.push(getCharFromInt(context_data_val));
context_data_val = 0;
}
else {
context_data_position++;
}
value = value >> 1;
}
}
context_enlargeIn--;
if (context_enlargeIn == 0) {
context_enlargeIn = Math.pow(2, context_numBits);
context_numBits++;
}
}
// Mark the end of the stream
value = 2;
for (var i_11 = 0; i_11 < context_numBits; i_11++) {
context_data_val = (context_data_val << 1) | (value & 1);
if (context_data_position == bitsPerChar - 1) {
context_data_position = 0;
context_data.push(getCharFromInt(context_data_val));
context_data_val = 0;
}
else {
context_data_position++;
}
value = value >> 1;
}
// Flush the last char
while (true) {
context_data_val = (context_data_val << 1);
if (context_data_position == bitsPerChar - 1) {
context_data.push(getCharFromInt(context_data_val));
break;
}
else
context_data_position++;
}
return context_data.join('');
},
decompress: function (compressed) {
if (compressed == null)
return "";
if (compressed == "")
return null;
return LZString._decompress(compressed.length, 32768, function (index) { return compressed.charCodeAt(index); });
},
_decompress: function (length, resetValue, getNextValue) {
var dictionary = [], next, enlargeIn = 4, dictSize = 4, numBits = 3, entry = "", result = [], i, w, bits, resb, maxpower, power, c, data = { val: getNextValue(0), position: resetValue, index: 1 };
for (var i_12 = 0; i_12 < 3; i_12 += 1) {
dictionary[i_12] = i_12;
}
bits = 0;
maxpower = Math.pow(2, 2);
power = 1;
while (power != maxpower) {
resb = data.val & data.position;
data.position >>= 1;
if (data.position == 0) {
data.position = resetValue;
data.val = getNextValue(data.index++);
}
bits |= (resb > 0 ? 1 : 0) * power;
power <<= 1;
}
switch (next = bits) {
case 0:
bits = 0;
maxpower = Math.pow(2, 8);
power = 1;
while (power != maxpower) {
resb = data.val & data.position;
data.position >>= 1;
if (data.position == 0) {
data.position = resetValue;
data.val = getNextValue(data.index++);
}
bits |= (resb > 0 ? 1 : 0) * power;
power <<= 1;
}
c = f(bits);
break;
case 1:
bits = 0;
maxpower = Math.pow(2, 16);
power = 1;
while (power != maxpower) {
resb = data.val & data.position;
data.position >>= 1;
if (data.position == 0) {
data.position = resetValue;
data.val = getNextValue(data.index++);
}
bits |= (resb > 0 ? 1 : 0) * power;
power <<= 1;
}
c = f(bits);
break;
case 2:
return "";
}
dictionary[3] = c;
w = c;
result.push(c);
while (true) {
if (data.index > length) {
return "";
}
bits = 0;
maxpower = Math.pow(2, numBits);
power = 1;
while (power != maxpower) {
resb = data.val & data.position;
data.position >>= 1;
if (data.position == 0) {
data.position = resetValue;
data.val = getNextValue(data.index++);
}
bits |= (resb > 0 ? 1 : 0) * power;
power <<= 1;
}
switch (c = bits) {
case 0:
bits = 0;
maxpower = Math.pow(2, 8);
power = 1;
while (power != maxpower) {
resb = data.val & data.position;
data.position >>= 1;
if (data.position == 0) {
data.position = resetValue;
data.val = getNextValue(data.index++);
}
bits |= (resb > 0 ? 1 : 0) * power;
power <<= 1;
}
dictionary[dictSize++] = f(bits);
c = dictSize - 1;
enlargeIn--;
break;
case 1:
bits = 0;
maxpower = Math.pow(2, 16);
power = 1;
while (power != maxpower) {
resb = data.val & data.position;
data.position >>= 1;
if (data.position == 0) {
data.position = resetValue;
data.val = getNextValue(data.index++);
}
bits |= (resb > 0 ? 1 : 0) * power;
power <<= 1;
}
dictionary[dictSize++] = f(bits);
c = dictSize - 1;
enlargeIn--;
break;
case 2:
return result.join('');
}
if (enlargeIn == 0) {
enlargeIn = Math.pow(2, numBits);
numBits++;
}
if (dictionary[c]) {
entry = dictionary[c];
}
else {
if (c === dictSize) {
entry = w + w.charAt(0);
}
else {
return null;
}
}
result.push(entry);
// Add w+entry[0] to the dictionary.
dictionary[dictSize++] = w + entry.charAt(0);
enlargeIn--;
w = entry;
if (enlargeIn == 0) {
enlargeIn = Math.pow(2, numBits);
numBits++;
}
}
}
};
return LZString;
})();
/* tslint:enable */
setTimeout(WideAngleLens, 1000);
})(WMEWAL || (WMEWAL = {}));