<commit_before>var style; //MapBox API
var token; //MapBox API
var map; // Leaflet map
var url; // String
var markers; //FeatureGroup
var drawnShapes; //FeatureGroup
var MLFeatures; // Array
var selections; // Object

// Start! Initialize the map and all things awesome.
// For debugging, check MarkLogic's 8040_ErrorLog.txt
// and your browser's inspection tool
start();

// Run this function before any other
function start() {
  style = keys.mapboxStyle;
  token = keys.mapboxToken;

  // Leaflet's map initialization method
  // 'mapid' is the div's name where the map will be found on the web page.
  map = L.map('mapid').setView([0, 0], 2);
  url = 'https://api.mapbox.com/styles/v1/liangdanica/' + style + '/tiles/256/{z}/{x}/{y}?access_token=' + token;

  L.tileLayer(url,
  {
    attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
      '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>',
    maxZoom: 18,
    id: 'Basic',
    accessToken: token
  }).addTo(map);

  // Initialize the FeatureGroup to store editable layers (shapes drawn by user)
  // ref: http://leafletjs.com/2013/02/20/guest-post-draw.html
  markers = new L.FeatureGroup();
  drawnShapes = new L.FeatureGroup();

  // Add the layers to the map so they are displayed
  map.addLayer(markers);
  map.addLayer(drawnShapes);

  //Selections will hold info on the current state of selected options to query
  selections = {
    features: [],
    industries: [],
    date1: "",
    date2: ""
  };

  // Load all MarkLogic feature and industry options for dropdown menus
  doPost('/search.sjs', drawPage, true);

  // After all industries and features are known, fetch the users from the database and display them
  doPost('/search.sjs', displayGeoJSON, false);

  addMapEvents();
}

function addMapEvents() {
  //drawControl is the map element that allows drawing and deleting of shapes/layers
  var drawControl = new L.Control.Draw({
    edit: { //allows editing/deleting of drawn shapes on map
      featureGroup: drawnShapes
    }, //https://github.com/Leaflet/Leaflet.draw/wiki/API-Reference#lcontroldraw
    draw: { //all shapes enabled by default
      polyline: false, //disable polylines
      marker: false, // disable markers
      circle: false // disable circles, additional code required to implement, not supported by geojson
    }
  });
  map.addControl(drawControl);

  // Events
  map.on('draw:created', function (e) {
    drawnShapes.addLayer(e.layer);
    doPost("/search.sjs", displayGeoJSON, false);
  });
  map.on('draw:edited', function (e) {
    doPost("/search.sjs", displayGeoJSON, false);
  });
  map.on('draw:deleted', function (e) {
    // Update db to save latest changes.
    drawnShapes.removeLayer(e.layer);
  });
  map.on('zoomend', function (e) {
    doPost("/search.sjs", displayGeoJSON, false);
  })
  map.on('drag', function (e) {
    doPost("/search.sjs", displayGeoJSON, false);
  })

}

// function clearResults() {
//   $('#collapse1 ul').empty();
//   $('#collapse2 ul').empty();
//   map.on('draw:deleted', function (e) {
//     // update db to save latest changes
//     drawnShapes.removeLayer(e.layer);
//   });
// }

// Draw markers on map
function drawPage(response) {
  displayIndustries(response.facets.Industry);
  displayFeatures(response.features.MarkLogicFeatures);
}

/**Copied from <NAME> and <NAME>'s geoapp and modified**/
function doPost(url, success, firstLoad) {

  var payload = {
    selections: selections,
    mapWindow: [ //Used for search if no drawn shapes
      map.getBounds().getSouth(),
      map.getBounds().getWest(),
      map.getBounds().getNorth(),
      map.getBounds().getEast()
    ],
    firstLoad: firstLoad,
    searchRegions: drawnShapes.toGeoJSON()
  };

  $.ajax({
    type: "POST",
    url: url,
    data: JSON.stringify(payload),
    contentType: "application/json",
    dataType: "json",
    success: success,
    error: fail
  });
}

function fail(jqXHR, status, errorThrown) {
  console.log(errorThrown);
}

//features is an array []
function displayFeatures(features) {

  for (var ndx in features) {
    var count = features[ndx]; // frequency of each feature
    $('#collapse2 ul').append('<li class="list-group-item"><input checked type="checkbox"class="fChecker"value='+features[ndx]+'>'+features[ndx]+'</li>');
    // Commented out because no feature data yet in database
    //selections.features.push(features[ndx].toString());
  }
  var $features =  $("#featureUL .fChecker");
  for (var i = 0; i < $features.length; i++) {
    $features[i].onclick = function(e) {
      if (e.target.value === 0) {
        // e.target.value is 0 when click is on text in html and not on the check box
      }
      else {
        // Commented out for now because no feature data in database.
        //updateSelections("Feature", e.target.nextSibling.data);
        //doPost("/search.sjs", displayGeoJSON, false);
      }
    }
  }
}

// industries is an object {}
function displayIndustries(industries) {

  for (var obj in industries) {
    var count = industries[obj]; // frequency of each industry
    $('#collapse1 ul').append('<li class="list-group-item"><input checked type="checkbox"class="iChecker"value='+obj+'>'+obj+'<i>('+count+')</i></li>');
    //Add value to the selections so code works with what is being displayed
    selections.industries.push(obj.toString());
  }
  // Problem lives with how the UL is selected adnd what it is receiving,
  var $industries =  $("#industryUL .iChecker");

  // Conveniently the length property here refers to the number of elements appended to the selector
  // aka stuff not normally there, in other words, the length is the number of industries in the UL.
  // and they occur at properties 0 -> $industries.length (y) Thank you, God.
  for (var i = 0; i < $industries.length; i++) {
    $industries[i].onclick = function(e) {
      if (e.target.value === 0) {
        // e.target.value is 0 when click is on text in html and not on the check box
      }
      else {
        updateSelections("Industry", e.target.nextSibling.data);
        doPost("/search.sjs", displayGeoJSON, false);
      }
    }
  }

}

function updateSelections(which, value) {
  var index;
  if (which === "Industry") {
    // check if value is in the array
    index = selections.industries.indexOf(value);
    if (index > -1) { //unchecked the box
      // Already in the array, aka checked already, so unchecking was done
      selections.industries.splice(index, 1);
    }
    else { //checked the box
      selections.industries.push(value);
    }
  }
  else if (which === "Feature") {
    index = selections.features.indexOf(value);<commit_msg>Stable version of map to play with<commit_after>var style; //MapBox API
var token; //MapBox API
var map; // Leaflet map
var url; // String
var markers; //FeatureGroup
var drawnShapes; //FeatureGroup
var MLFeatures; // Array
var selections; // Object

// Start! Initialize the map and all things awesome.
// For debugging, check MarkLogic's 8040_ErrorLog.txt
// and your browser's inspection tool
start();

// Run this function before any other
function start() {
  style = keys.mapboxStyle;
  token = keys.mapboxToken;

  // Leaflet's map initialization method
  // 'mapid' is the div's name where the map will be found on the web page.
  map = L.map('mapid').setView([0, 0], 2);
  url = 'https://api.mapbox.com/styles/v1/liangdanica/' + style + '/tiles/256/{z}/{x}/{y}?access_token=' + token;

  L.tileLayer(url,
  {
    attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
      '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>',
    maxZoom: 18,
    id: 'Basic',
    accessToken: token
  }).addTo(map);

  // Initialize the FeatureGroup to store editable layers (shapes drawn by user)
  // ref: http://leafletjs.com/2013/02/20/guest-post-draw.html
  markers = new L.FeatureGroup();
  drawnShapes = new L.FeatureGroup();

  // Add the layers to the map so they are displayed
  map.addLayer(markers);
  map.addLayer(drawnShapes);

  //Selections will hold info on the current state of selected options to query
  selections = {
    features: [],
    industries: [],
    date1: "",
    date2: ""
  };

  // Load all MarkLogic feature and industry options for dropdown menus
  doPost('/search.sjs', drawPage, true);

  // After all industries and features are known, fetch the users from the database and display them
  doPost('/search.sjs', displayGeoJSON, false);

  addMapEvents();
}

function addMapEvents() {
  //drawControl is the map element that allows drawing and deleting of shapes/layers
  var drawControl = new L.Control.Draw({
    edit: { //allows editing/deleting of drawn shapes on map
      featureGroup: drawnShapes
    }, //https://github.com/Leaflet/Leaflet.draw/wiki/API-Reference#lcontroldraw
    draw: { //all shapes enabled by default
      polyline: false, //disable polylines
      marker: false, // disable markers
      circle: false // disable circles, additional code required to implement, not supported by geojson
    }
  });
  map.addControl(drawControl);

  // Events
  map.on('draw:created', function (e) {
    drawnShapes.addLayer(e.layer);
    doPost("/search.sjs", displayGeoJSON, false);
  });
  map.on('draw:edited', function (e) {
    doPost("/search.sjs", displayGeoJSON, false);
  });
  map.on('draw:deleted', function (e) {
    // Update db to save latest changes.
    drawnShapes.removeLayer(e.layer);
  });
  map.on('zoomend', function (e) {
    doPost("/search.sjs", displayGeoJSON, false);
  })
  map.on('drag', function (e) {
    doPost("/search.sjs", displayGeoJSON, false);
  })

}

// function clearResults() {
//   $('#collapse1 ul').empty();
//   $('#collapse2 ul').empty();
//   map.on('draw:deleted', function (e) {
//     // update db to save latest changes
//     drawnShapes.removeLayer(e.layer);
//   });
// }

// Draw markers on map
function drawPage(response) {
  displayIndustries(response.facets.Industry);
  displayFeatures(response.features.MarkLogicFeatures);
}

/**Copied from <NAME> and <NAME>'s geoapp and modified**/
function doPost(url, success, firstLoad) {

  var payload = {
    selections: selections,
    mapWindow: [ //Used for search if no drawn shapes
      map.getBounds().getSouth(),
      map.getBounds().getWest(),
      map.getBounds().getNorth(),
      map.getBounds().getEast()
    ],
    firstLoad: firstLoad,
    searchRegions: drawnShapes.toGeoJSON()
  };

  $.ajax({
    type: "POST",
    url: url,
    data: JSON.stringify(payload),
    contentType: "application/json",
    dataType: "json",
    success: success,
    error: fail
  });
}

function fail(jqXHR, status, errorThrown) {
  console.log(errorThrown);
}

//features is an array []
function displayFeatures(features) {

  for (var ndx in features) {
    var count = features[ndx]; // frequency of each feature
    $('#collapse2 ul').append('<li class="list-group-item"><input checked type="checkbox"class="fChecker"value='+features[ndx]+'>'+features[ndx]+'</li>');
    // Commented out because no feature data yet in database
    //selections.features.push(features[ndx].toString());
  }
  var $features =  $("#featureUL .fChecker");
  for (var i = 0; i < $features.length; i++) {
    $features[i].onclick = function(e) {
      if (e.target.value === 0) {
        // e.target.value is 0 when click is on text in html and not on the check box
      }
      else {
        // Commented out for now because no feature data in database.
        //updateSelections("Feature", e.target.nextSibling.data);
        //doPost("/search.sjs", displayGeoJSON, false);
      }
    }
  }
}

// industries is an object {}
function displayIndustries(industries) {

  for (var obj in industries) {
    var count = industries[obj]; // frequency of each industry
    $('#collapse1 ul').append('<li class="list-group-item"><input checked type="checkbox"class="iChecker"value='+obj+'>'+obj+'<i>('+count+')</i></li>');
    //Add value to the selections so code works with what is being displayed
    selections.industries.push(obj.toString());
  }
  // Problem lives with how the UL is selected adnd what it is receiving,
  var $industries =  $("#industryUL .iChecker");

  // Conveniently the length property here refers to the number of elements appended to the selector
  // AKA stuff not normally there, in other words, the length is the number of industries in the UL.
  // and they occur at properties 0 -> $industries.length (y) Thank you, God.
  for (var i = 0; i < $industries.length; i++) {
    $industries[i].onclick = function(e) {
      if (e.target.value === 0) {
        // e.target.value is 0 when click is on text in html and not on the check box
      }
      else {
        updateSelections("Industry", e.target.nextSibling.data);
        doPost("/search.sjs", displayGeoJSON, false);
      }
    }
  }

}

function updateSelections(which, value) {
  var index;
  if (which === "Industry") {
    // Check if value is in the array
    index = selections.industries.indexOf(value);
    if (index > -1) { //unchecked the box
      // Already in the array, aka box was checked, so unchecking was just done
      selections.industries.splice(index, 1);
    }
    else { //checked the box
      selections.industries.push(value);
    }
  }
  else if (which === "Feature") {
    index = selections.features.indexOf(value);
{'fraction_non_alphanumeric': 0.1446940585279338, 'fraction_numerical': 0.005616316878510198, 'mean_word_length': 3.209331259720062, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6768961', 'n_tokens_mistral': 4327, 'n_tokens_neox': 4196, 'n_words': 1243}