<commit_before>const logger = require('winston');
const changelog = require('changelog');
const github = require('./api/github');
const versionsHelper = require('./helpers/versions');
const packageJson = require('./helpers/package-json');
const npmApi = require('./api/npm');

let config = null;

module.exports = renovate;

// This function manages the queue per-package file
function renovate(repoName, packageFile, setConfig) {
  // Initialize globals
  config = Object.assign({}, setConfig);
  config.packageFile = packageFile;

  logger.info(`Processing ${repoName} ${packageFile}`);

  // Start the chain
  return github.getFileContents(packageFile)
    .then(checkforRenovateConfig)
    .then(contents => packageJson.extractDependencies(contents, config.depTypes))
    .then(filterIgnoredDependencies)
    .then(findUpgrades)
    .then(processUpgradesSequentially)
    .then(() => { // eslint-disable-line promise/always-return
      logger.info(`${repoName} ${packageFile} done`);
    })
    .catch((error) => {
      logger.error(`renovate caught error: ${error}`);
    });
}

function checkforRenovateConfig(packageContent) {
  if (packageContent.renovate) {
    logger.debug('Found renovate configuration in package file');
    Object.assign(config, packageContent.renovate);
    logger.debug(`Updated config: ${JSON.stringify(config)}`);
  }
  return packageContent;
}

// Remove any dependencies that are on the ignore list
function filterIgnoredDependencies(dependencies) {
  return dependencies.filter(dependency => config.ignoreDeps.indexOf(dependency.depName) === -1);
}

function findUpgrades(dependencies) {
  const allDependencyUpgrades = [];
  // We create an array of promises so that they can be executed in parallel
  const allDependencyPromises = dependencies.reduce((promises, dep) => promises.concat(
    npmApi.getDependency(dep.depName)
    .then(npmDependency =>
      versionsHelper.determineUpgrades(npmDependency, dep.currentVersion, config))
    .then((upgrades) => {
      if (upgrades.length > 0) {
        logger.verbose(`${dep.depName}: Upgrades = ${JSON.stringify(upgrades)}`);
        upgrades.forEach((upgrade) => {
          allDependencyUpgrades.push(Object.assign({}, dep, upgrade));
        });
      } else {
        logger.verbose(`${dep.depName}: No upgrades required`);
      }
      return Promise.resolve();
    })
    .catch((error) => {
      logger.error(`Error finding upgrades for ${dep.depName}: ${error}`);
    })), []);
  // Return the upgrade array once all Promises are complete
  return Promise.all(allDependencyPromises).then(() => allDependencyUpgrades);
}

function processUpgradesSequentially(upgrades) {
  if (Object.keys(upgrades).length) {
    logger.verbose('Processing upgrades');
  } else {
    logger.verbose('No upgrades to process');
  }
  logger.verbose(`All upgrades: ${JSON.stringify(upgrades)}`);
  // We are processing each upgrade sequentially for two major reasons:
  // 1. Reduce chances of GitHub API rate limiting
  // 2. Edge case collision of branch name, e.g. dependency also listed as dev dependency
  return upgrades.reduce(
    (promise, upgrade) => promise
      .then(() => updateDependency(upgrade)), Promise.resolve());
}

function updateDependency(upgrade) {
  // Expand upgrade params
  const depType = upgrade.depType;
  const depName = upgrade.depName;
  const newVersion = upgrade.newVersion;
  // Use templates to generate strings
  const branchName = config.templates.branchName(upgrade);
  let commitFunction = null;
  let prFunction = null;
  if (upgrade.upgradeType === 'pin') {
    commitFunction = config.templates.commitMessagePin;
    prFunction = config.templates.prTitlePin;
  } else if (upgrade.upgradeType === 'minor') {
    // Use same title for range or minor
    commitFunction = config.templates.commitMessage;
    prFunction = config.templates.prTitleMinor;
  } else {
    commitFunction = config.templates.commitMessage;
    prFunction = config.templates.prTitleMajor;
  }
  const commitMessage = commitFunction(upgrade);
  const prTitle = prFunction(upgrade);

  return checkForUnmergeablePr()
  .then(ensureBranch)
  .then(ensureCommit)
  .then(getChangelog)
  .then(log => ensurePr(log))
  .catch((error) => {
    if (error === 'PR exists') {
      logger.verbose(`Skipping ${depName} upgrade as matching closed PR already existed`);
    } else {
      logger.error(`Error updating dependency ${depName}: ${error}`);
    }
    // Don't throw here - we don't want to stop the other renovations
  });

  // Check if same PR already existed and skip if so
  // This allows users to close an unwanted upgrade PR and not worry about seeing it raised again
  function checkForClosedPr() {
    if (config.recreateClosed) {
      logger.debug(`${depName}: Skipping closed PR check`);
      return Promise.resolve();
    }
    logger.debug(`${depName}: Checking for closed PR`);
    return github.checkForClosedPr(branchName, prTitle).then((prExisted) => {
      logger.debug(`Closed PR existed: ${prExisted}`);
      if (prExisted) {
        return Promise.reject('PR exists');
      }
      return Promise.resolve();
    });
  }

  function getBranchPr() {
    return github.getBranchPr(branchName)
    .then((branchPr) => {
      if (branchPr) {
        logger.debug(`Found open PR for ${branchName}`);
        return github.getPr(branchPr.number);
      }
      logger.debug(`Didn't find open PR for ${branchName}`);
      return null;
    });
  }

  function deleteUnmergeablePr(pr) {
    return github.updatePr(pr.number, `${pr.title} (unmergeable)`)
      .then(() => github.deleteBranch(branchName));
  }

  function checkForUnmergeablePr() {
    return getBranchPr()
    .then((pr) => {
      if (pr) {
        logger.debug(`checkForUnmergeablePr found PR #${pr.number}`);
        if (pr.mergeable === false) {
          logger.debug(`Existing PR ${pr.number} is not mergeable`);
          if (pr.additions * pr.deletions === 1) {
            // No other changes except ours
            logger.verbose(`Deleting branch ${branchName}`);
            // Rename PR and then delete the branch
            return deleteUnmergeablePr(pr);
          }
          logger.verbose(`Not deleting branch ${branchName} because it has additional changes`);
        }
        return Promise.resolve();
      }
      // If no open PR exists then check for any closed one
      return checkForClosedPr();
    });
  }

  function ensureBranch() {
    // Save an API call by attempting to create branch without checking for existence first
    return github.createBranch(branchName).catch((error) => {
      // Check in case it's because the branch already existed
      if (error.response.body.message !== 'Reference already exists') {
        // In this case it means we really do have a problem and can't continue
        logger.error(`Error creating branch: ${branchName}`);
        logger.error(`Response: ${JSON.stringify(error.response.body)}`);
        throw error;
      }
      // Otherwise we swallow this error and continue
    });
  }
  function ensureCommit() {
    // Retrieve the package.json from this renovate branch
    return github.getFile(config.packageFile, branchName).then((res) => {
      const currentSHA = res.body.sha;
      const currentFileContent = new Buffer(res.body.content, 'base64').toString();
      const currentJson = JSON.parse(currentFileContent);
      if (currentJson[depType][depName] === newVersion) {
        logger.verbose(`${depName}: branch ${branchName} is already up-to-date`);
        return Promise.resolve();
      }
      // Branch must need updating
      logger.verbose(`${depName}: Updating to ${newVersion} in branch ${branchName}`);
      const newPackageContents = packageJson.setNewValue(
        currentFileContent,
        depType,
        depName,
        newVersion);
      return github.writeFile(
        branchName,
        currentSHA,
        config.packageFile,
        newPackageContents,
        commitMessage);
    })
    .catch((error) => {
      logger.error(`${depName} ensureCommit error: ${error}`);
      throw error;
    });
  }

  function getChangelog() {
    if (!upgrade.workingVersion || upgrade.workingVersion === upgrade.newVersion) {
      return Object.assign(upgrade, { changelog: '' });
    }
    const semverString = `>${upgrade.workingVersion} <=${upgrade.newVersion}`;
    let log = '';
    logger.debug(`semverString: ${semverString}`);
    return changelog.generate(upgrade.depName, semverString)
      .then(changelog.markdown)
      .then((res) => {
        log = res;
        return logger.silly(`${upgrade.depName} ${upgrade.newVersion} changelog: ${res}`);
      })
      .catch((error) => {
        logger.verbose(`getChangelog error: ${error}`);
      })
      .then(() => Object.assign(upgrade, { changelog: log }));
  }

  // Ensures that PR exists with matching title/body
  function ensurePr(upgradeWithChangeLog) {
    logger.debug('Ensuring PR');

    const prBody = config.templates.prBody(upgradeWithChangeLog);

    return github.getBranchPr(branchName)
    .then(processExistingPr)
    .catch((error) => {
      logger.error(`${depName} failed to ensure PR: ${error}`);
    });

    // Create PR based on current state
    function createPr() {
      return github.createPr(branchName, prTitle, prBody).then((newPr) => {
        logger.info(`${depName}: Created PR #${newPr.number}`);
        return newPr.number;
      });
    }
    // Update PR based on current state
    function updatePr(existingPr) {
      logger.debug(`updatePr: ${existingPr.number}`);
      return github.updatePr(existingPr.number, prTitle, prBody).then(() => {
        logger.info(`${depName}: Updated PR #${existingPr.number}`);
        return Promise.resolve();
      });
    }
    // Process a returned PR
    function processExistingPr(existingPr) {
      if (!existingPr) {
        logger.debug(`Didn't find existing PR for branch ${branchName}`);
        // We need to create a new PR
        return createPr().then(prNo => addLabels(prNo));
      }
      // Check if existing PR needs updating
      logger.debug(`processExistingPr: ${existingPr.number}`);
      if (existingPr.title === prTitle && existingPr.body === prBody) {
        logger.verbose(`${depName}: PR #${existingPr.number} already up-to-date`);
        return Promise.resolve();
      }
      // PR must need updating
      return updatePr(existingPr);
    }

    // Add labels to a PR
    function addLabels(prNo) {
      if (config.labels.length === 0) {
        logger.silly(`No labels to add to ${prNo}`);
        return Promise.resolve();
      }
      return github.addLabels(prNo, config.labels);
    }
  }
}
<commit_msg>Fix umergeable check<commit_after>const logger = require('winston');
const changelog = require('changelog');
const github = require('./api/github');
const versionsHelper = require('./helpers/versions');
const packageJson = require('./helpers/package-json');
const npmApi = require('./api/npm');

let config = null;

module.exports = renovate;

// This function manages the queue per-package file
function renovate(repoName, packageFile, setConfig) {
  // Initialize globals
  config = Object.assign({}, setConfig);
  config.packageFile = packageFile;

  logger.info(`Processing ${repoName} ${packageFile}`);

  // Start the chain
  return github.getFileContents(packageFile)
    .then(checkforRenovateConfig)
    .then(contents => packageJson.extractDependencies(contents, config.depTypes))
    .then(filterIgnoredDependencies)
    .then(findUpgrades)
    .then(processUpgradesSequentially)
    .then(() => { // eslint-disable-line promise/always-return
      logger.info(`${repoName} ${packageFile} done`);
    })
    .catch((error) => {
      logger.error(`renovate caught error: ${error}`);
    });
}

function checkforRenovateConfig(packageContent) {
  if (packageContent.renovate) {
    logger.debug('Found renovate configuration in package file');
    Object.assign(config, packageContent.renovate);
    logger.debug(`Updated config: ${JSON.stringify(config)}`);
  }
  return packageContent;
}

// Remove any dependencies that are on the ignore list
function filterIgnoredDependencies(dependencies) {
  return dependencies.filter(dependency => config.ignoreDeps.indexOf(dependency.depName) === -1);
}

function findUpgrades(dependencies) {
  const allDependencyUpgrades = [];
  // We create an array of promises so that they can be executed in parallel
  const allDependencyPromises = dependencies.reduce((promises, dep) => promises.concat(
    npmApi.getDependency(dep.depName)
    .then(npmDependency =>
      versionsHelper.determineUpgrades(npmDependency, dep.currentVersion, config))
    .then((upgrades) => {
      if (upgrades.length > 0) {
        logger.verbose(`${dep.depName}: Upgrades = ${JSON.stringify(upgrades)}`);
        upgrades.forEach((upgrade) => {
          allDependencyUpgrades.push(Object.assign({}, dep, upgrade));
        });
      } else {
        logger.verbose(`${dep.depName}: No upgrades required`);
      }
      return Promise.resolve();
    })
    .catch((error) => {
      logger.error(`Error finding upgrades for ${dep.depName}: ${error}`);
    })), []);
  // Return the upgrade array once all Promises are complete
  return Promise.all(allDependencyPromises).then(() => allDependencyUpgrades);
}

function processUpgradesSequentially(upgrades) {
  if (Object.keys(upgrades).length) {
    logger.verbose('Processing upgrades');
  } else {
    logger.verbose('No upgrades to process');
  }
  logger.verbose(`All upgrades: ${JSON.stringify(upgrades)}`);
  // We are processing each upgrade sequentially for two major reasons:
  // 1. Reduce chances of GitHub API rate limiting
  // 2. Edge case collision of branch name, e.g. dependency also listed as dev dependency
  return upgrades.reduce(
    (promise, upgrade) => promise
      .then(() => updateDependency(upgrade)), Promise.resolve());
}

function updateDependency(upgrade) {
  // Expand upgrade params
  const depType = upgrade.depType;
  const depName = upgrade.depName;
  const newVersion = upgrade.newVersion;
  // Use templates to generate strings
  const branchName = config.templates.branchName(upgrade);
  let commitFunction = null;
  let prFunction = null;
  if (upgrade.upgradeType === 'pin') {
    commitFunction = config.templates.commitMessagePin;
    prFunction = config.templates.prTitlePin;
  } else if (upgrade.upgradeType === 'minor') {
    // Use same title for range or minor
    commitFunction = config.templates.commitMessage;
    prFunction = config.templates.prTitleMinor;
  } else {
    commitFunction = config.templates.commitMessage;
    prFunction = config.templates.prTitleMajor;
  }
  const commitMessage = commitFunction(upgrade);
  const prTitle = prFunction(upgrade);

  return checkForUnmergeablePr()
  .then(ensureBranch)
  .then(ensureCommit)
  .then(getChangelog)
  .then(log => ensurePr(log))
  .catch((error) => {
    if (error === 'PR exists') {
      logger.verbose(`Skipping ${depName} upgrade as matching closed PR already existed`);
    } else {
      logger.error(`Error updating dependency ${depName}: ${error}`);
    }
    // Don't throw here - we don't want to stop the other renovations
  });

  // Check if same PR already existed and skip if so
  // This allows users to close an unwanted upgrade PR and not worry about seeing it raised again
  function checkForClosedPr() {
    if (config.recreateClosed) {
      logger.debug(`${depName}: Skipping closed PR check`);
      return Promise.resolve();
    }
    logger.debug(`${depName}: Checking for closed PR`);
    return github.checkForClosedPr(branchName, prTitle).then((prExisted) => {
      logger.debug(`Closed PR existed: ${prExisted}`);
      if (prExisted) {
        return Promise.reject('PR exists');
      }
      return Promise.resolve();
    });
  }

  function getBranchPr() {
    return github.getBranchPr(branchName)
    .then((branchPr) => {
      if (branchPr) {
        logger.debug(`Found open PR for ${branchName}`);
        return github.getPr(branchPr.number);
      }
      logger.debug(`Didn't find open PR for ${branchName}`);
      return null;
    });
  }

  function deleteUnmergeablePr(pr) {
    return github.updatePr(pr.number, `${pr.title} (unmergeable)`)
      .then(() => github.deleteBranch(branchName));
  }

  function checkForUnmergeablePr() {
    return getBranchPr()
    .then((pr) => {
      if (pr) {
        logger.debug(`checkForUnmergeablePr found PR #${pr.number}`);
        if (pr.mergeable_state === 'dirty') {
          logger.debug(`Existing PR ${pr.number} is not mergeable`);
          if (pr.additions * pr.deletions === 1) {
            // No other changes except ours
            logger.verbose(`Deleting branch ${branchName}`);
            // Rename PR and then delete the branch
            return deleteUnmergeablePr(pr);
          }
          logger.verbose(`Not deleting branch ${branchName} because it has additional changes`);
        }
        return Promise.resolve();
      }
      // If no open PR exists then check for any closed one
      return checkForClosedPr();
    });
  }

  function ensureBranch() {
    // Save an API call by attempting to create branch without checking for existence first
    return github.createBranch(branchName).catch((error) => {
      // Check in case it's because the branch already existed
      if (error.response.body.message !== 'Reference already exists') {
        // In this case it means we really do have a problem and can't continue
        logger.error(`Error creating branch: ${branchName}`);
        logger.error(`Response: ${JSON.stringify(error.response.body)}`);
        throw error;
      }
      // Otherwise we swallow this error and continue
    });
  }
  function ensureCommit() {
    // Retrieve the package.json from this renovate branch
    return github.getFile(config.packageFile, branchName).then((res) => {
      const currentSHA = res.body.sha;
      const currentFileContent = new Buffer(res.body.content, 'base64').toString();
      const currentJson = JSON.parse(currentFileContent);
      if (currentJson[depType][depName] === newVersion) {
        logger.verbose(`${depName}: branch ${branchName} is already up-to-date`);
        return Promise.resolve();
      }
      // Branch must need updating
      logger.verbose(`${depName}: Updating to ${newVersion} in branch ${branchName}`);
      const newPackageContents = packageJson.setNewValue(
        currentFileContent,
        depType,
        depName,
        newVersion);
      return github.writeFile(
        branchName,
        currentSHA,
        config.packageFile,
        newPackageContents,
        commitMessage);
    })
    .catch((error) => {
      logger.error(`${depName} ensureCommit error: ${error}`);
      throw error;
    });
  }

  function getChangelog() {
    if (!upgrade.workingVersion || upgrade.workingVersion === upgrade.newVersion) {
      return Object.assign(upgrade, { changelog: '' });
    }
    const semverString = `>${upgrade.workingVersion} <=${upgrade.newVersion}`;
    let log = '';
    logger.debug(`semverString: ${semverString}`);
    return changelog.generate(upgrade.depName, semverString)
      .then(changelog.markdown)
      .then((res) => {
        log = res;
        return logger.silly(`${upgrade.depName} ${upgrade.newVersion} changelog: ${res}`);
      })
      .catch((error) => {
        logger.verbose(`getChangelog error: ${error}`);
      })
      .then(() => Object.assign(upgrade, { changelog: log }));
  }

  // Ensures that PR exists with matching title/body
  function ensurePr(upgradeWithChangeLog) {
    logger.debug('Ensuring PR');

    const prBody = config.templates.prBody(upgradeWithChangeLog);

    return github.getBranchPr(branchName)
    .then(processExistingPr)
    .catch((error) => {
      logger.error(`${depName} failed to ensure PR: ${error}`);
    });

    // Create PR based on current state
    function createPr() {
      return github.createPr(branchName, prTitle, prBody).then((newPr) => {
        logger.info(`${depName}: Created PR #${newPr.number}`);
        return newPr.number;
      });
    }
    // Update PR based on current state
    function updatePr(existingPr) {
      logger.debug(`updatePr: ${existingPr.number}`);
      return github.updatePr(existingPr.number, prTitle, prBody).then(() => {
        logger.info(`${depName}: Updated PR #${existingPr.number}`);
        return Promise.resolve();
      });
    }
    // Process a returned PR
    function processExistingPr(existingPr) {
      if (!existingPr) {
        logger.debug(`Didn't find existing PR for branch ${branchName}`);
        // We need to create a new PR
        return createPr().then(prNo => addLabels(prNo));
      }
      // Check if existing PR needs updating
      logger.debug(`processExistingPr: ${existingPr.number}`);
      if (existingPr.title === prTitle && existingPr.body === prBody) {
        logger.verbose(`${depName}: PR #${existingPr.number} already up-to-date`);
        return Promise.resolve();
      }
      // PR must need updating
      return updatePr(existingPr);
    }

    // Add labels to a PR
    function addLabels(prNo) {
      if (config.labels.length === 0) {
        logger.silly(`No labels to add to ${prNo}`);
        return Promise.resolve();
      }
      return github.addLabels(prNo, config.labels);
    }
  }
}
<|endoftext|>


<commit_before>function geoLocate(map) {
  return function(event) {
    map.locate({ setView: true });
  }
}

function add_map_controls(map) {
  map.removeControl(map.zoomControl);
  map.addControl(L.control.zoom({
    zoomInTitle: gettext("Zoom in"),
    zoomOutTitle: gettext("Zoom out")
  }));

  var Geolocate = L.Control.extend({
    options: {
      position: 'topleft'
    },

    onAdd: function(map) {
      var controlDiv = L.DomUtil.create(
        'div', 'leaflet-bar leaflet-control leaflet-control-geolocate'
      );
      controlDiv.title = gettext('Go to my location');
      L.DomEvent
       .addListener(controlDiv, 'click', L.DomEvent.stopPropagation)
       .addListener(controlDiv, 'click', L.DomEvent.preventDefault)
       .addListener(controlDiv, 'click', geoLocate(map));

      L.DomUtil.create('span', 'glyphicon glyphicon-map-marker', controlDiv);

      return controlDiv;
    }
  });

  map.addControl(new Geolocate());

  return map
}

function renderFeatures(map, featuresUrl, options) {
  options = options || {};

  function locationToFront() {
    if (options.location) {
      options.location.bringToFront();
    }
  }

  function allFeaturesLoaded() {
    $('#messages #loading').addClass('hidden');
    if (options.fitBounds === 'locations') {
      var bounds = markers.getBounds();
      if (bounds.isValid()) {
        map.fitBounds(bounds);
      }
    }
    locationToFront();
  }

  function loadFeatures(url) {
    $('#messages #loading').removeClass('hidden');
    return $.get(url, function(response) {
      geoJson.addData(response);

      // On first response, request all subsequent pages concurrently
      if (response.next && !response.previous) {
        items_per_page = response.features.length;
        total_items = response.count;
        total_pages = Math.ceil(total_items / items_per_page);

        // Start requests
        var requests = [];
        for (var i = 2; i <= total_pages; i++) {
          requests.push(loadFeatures(url + '?page=' + i, map, options.trans));
        }

        // Take action when all requests complete
        $.when.apply(this, requests).then(allFeaturesLoaded);

      // Handle situations where there is only 1 page of data
      } else if (!response.next && !response.previous) {
        allFeaturesLoaded()
      }
    });
  }

  var projectBounds;

  if (options.projectExtent) {
    var boundary = L.geoJson(
      options.projectExtent, {
        style: {
          stroke: true,
          color: "#0e305e",
          weight: 2,
          dashArray: "5, 5",
          opacity: 1,
          fill: false,
          clickable: false,
        }
      }
    );
    boundary.addTo(map);
    projectBounds = boundary.getBounds();
    if (options.fitBounds === 'project') {map.fitBounds(projectBounds);}
  } else {
    map.fitBounds([[-45.0, -180.0], [45.0, 180.0]]);
  }

  var geoJson = L.geoJson(null, {
    style: { weight: 2 },
    onEachFeature: function(feature, layer) {
      if (options.trans && options.projectUser) {
        layer.bindPopup("
" +
                      "
" + options.trans['location'] + "" +
                      feature.properties.type + "

" +
                      "
" + options.trans['open'] + ""  +
                      "
");
      }
    }
  });

  var markers = L.Deflate({minSize: 5, layerGroup: geoJson});
  markers.addTo(map);
  geoJson.addTo(map);

  if (options.location) {
    options.location.addTo(map);
    map.fitBounds(options.location.getBounds());
  } else if (projectBounds) {
    map.fitBounds(projectBounds);
  }
  loadFeatures(featuresUrl);
  map.on('zoomend', locationToFront);
  map.on('dragend', locationToFront);
}

function switch_layer_controls(map, options){
  // swap out default layer switcher
  var layers = options.djoptions.layers;
  var baseLayers = {};
  for (var l in layers){
    var layer = layers[l];
    var baseLayer = L.tileLayer(layer[1], layer[2]);
    baseLayers[layer[0]] = baseLayer;
  }
  // select first layer by default
  for (var l in baseLayers){
    map.addLayer(baseLayers[l]);
    break;
  }
  var groupedOptions = {
    groupCheckboxes: false
  };
  map.removeControl(map.layerscontrol);
  map.layerscontrol = L.control.groupedLayers(
    baseLayers, groupedOptions).addTo(map);
}

function add_spatial_resources(map, url){
  $.ajax(url).done(function(data){
    if (data.count == 0) return;
    var spatialResources = {};
    $.each(data.results, function (idx, resource) {
      var name = resource.name;
      var layers = {};
      $.each(resource.spatial_resources, function (i, spatial_resource) {
          var group = new L.LayerGroup();
          var layer = L.geoJson(spatial_resource.geom).addTo(group);
          layers[spatial_resource.name] = group
      });
      spatialResources[name] = layers;
    });
    $.each(spatialResources, function (sr) {
      var layers = spatialResources[sr];
      $.each(layers, function (layer) {
          map.layerscontrol.addOverlay(layers[layer], layer, sr);
      });
    });
  });
}

function enableMapEditMode() {
  var editButton = $('.leaflet-draw-edit-edit')[0];
  if (!editButton) {
    setTimeout(enableMapEditMode, 500);
  } else {
    var clickEvent = new MouseEvent('click');
    editButton.dispatchEvent(clickEvent);
  }
}

function saveOnMapEditMode() {
  var saveButton = $('.leaflet-draw-actions-top li:first-child a')[0];
  if (saveButton) {
    var clickEvent = new MouseEvent('click');
    saveButton.dispatchEvent(clickEvent);
  }
}
<commit_msg>Fix recursive async calls on location detail page (#2026)<commit_after>function geoLocate(map) {
  return function(event) {
    map.locate({ setView: true });
  }
}

function add_map_controls(map) {
  map.removeControl(map.zoomControl);
  map.addControl(L.control.zoom({
    zoomInTitle: gettext("Zoom in"),
    zoomOutTitle: gettext("Zoom out")
  }));

  var Geolocate = L.Control.extend({
    options: {
      position: 'topleft'
    },

    onAdd: function(map) {
      var controlDiv = L.DomUtil.create(
        'div', 'leaflet-bar leaflet-control leaflet-control-geolocate'
      );
      controlDiv.title = gettext('Go to my location');
      L.DomEvent
       .addListener(controlDiv, 'click', L.DomEvent.stopPropagation)
       .addListener(controlDiv, 'click', L.DomEvent.preventDefault)
       .addListener(controlDiv, 'click', geoLocate(map));

      L.DomUtil.create('span', 'glyphicon glyphicon-map-marker', controlDiv);

      return controlDiv;
    }
  });

  map.addControl(new Geolocate());

  return map
}

function renderFeatures(map, featuresUrl, options) {
  options = options || {};

  function locationToFront() {
    if (options.location) {
      options.location.bringToFront();
    }
  }

  function allFeaturesLoaded() {
    $('#messages #loading').addClass('hidden');
    if (options.fitBounds === 'locations') {
      var bounds = markers.getBounds();
      if (bounds.isValid()) {
        map.fitBounds(bounds);
      }
    }
    locationToFront();
  }

  function loadFeatures(url) {
    $('#messages #loading').removeClass('hidden');
    return $.get(url, function(response) {
      geoJson.addData(response);

      // On first response, request all subsequent pages concurrently
      if (response.next && !response.previous) {
        items_per_page = response.features.length;
        total_items = response.count;
        total_pages = Math.ceil(total_items / items_per_page);

        // Start requests
        var requests = [];
        for (var i = 2; i <= total_pages; i++) {
          var page = (url.indexOf('?') === -1 ? '?' : '&') + 'page=' + i;
          requests.push(loadFeatures(url + page, map, options.trans));
        }

        // Take action when all requests complete
        $.when.apply(this, requests).then(allFeaturesLoaded);

      // Handle situations where there is only 1 page of data
      } else if (!response.next && !response.previous) {
        allFeaturesLoaded()
      }
    });
  }

  var projectBounds;

  if (options.projectExtent) {
    var boundary = L.geoJson(
      options.projectExtent, {
        style: {
          stroke: true,
          color: "#0e305e",
          weight: 2,
          dashArray: "5, 5",
          opacity: 1,
          fill: false,
          clickable: false,
        }
      }
    );
    boundary.addTo(map);
    projectBounds = boundary.getBounds();
    if (options.fitBounds === 'project') {map.fitBounds(projectBounds);}
  } else {
    map.fitBounds([[-45.0, -180.0], [45.0, 180.0]]);
  }

  var geoJson = L.geoJson(null, {
    style: { weight: 2 },
    onEachFeature: function(feature, layer) {
      if (options.trans && options.projectUser) {
        layer.bindPopup("
" +
                      "
" + options.trans['location'] + "" +
                      feature.properties.type + "

" +
                      "
" + options.trans['open'] + ""  +
                      "
");
      }
    }
  });

  var markers = L.Deflate({minSize: 5, layerGroup: geoJson});
  markers.addTo(map);
  geoJson.addTo(map);

  if (options.location) {
    options.location.addTo(map);
    map.fitBounds(options.location.getBounds());
  } else if (projectBounds) {
    map.fitBounds(projectBounds);
  }
  loadFeatures(featuresUrl);
  map.on('zoomend', locationToFront);
  map.on('dragend', locationToFront);
}

function switch_layer_controls(map, options){
  // swap out default layer switcher
  var layers = options.djoptions.layers;
  var baseLayers = {};
  for (var l in layers){
    var layer = layers[l];
    var baseLayer = L.tileLayer(layer[1], layer[2]);
    baseLayers[layer[0]] = baseLayer;
  }
  // select first layer by default
  for (var l in baseLayers){
    map.addLayer(baseLayers[l]);
    break;
  }
  var groupedOptions = {
    groupCheckboxes: false
  };
  map.removeControl(map.layerscontrol);
  map.layerscontrol = L.control.groupedLayers(
    baseLayers, groupedOptions).addTo(map);
}

function add_spatial_resources(map, url){
  $.ajax(url).done(function(data){
    if (data.count == 0) return;
    var spatialResources = {};
    $.each(data.results, function (idx, resource) {
      var name = resource.name;
      var layers = {};
      $.each(resource.spatial_resources, function (i, spatial_resource) {
          var group = new L.LayerGroup();
          var layer = L.geoJson(spatial_resource.geom).addTo(group);
          layers[spatial_resource.name] = group
      });
      spatialResources[name] = layers;
    });
    $.each(spatialResources, function (sr) {
      var layers = spatialResources[sr];
      $.each(layers, function (layer) {
          map.layerscontrol.addOverlay(layers[layer], layer, sr);
      });
    });
  });
}

function enableMapEditMode() {
  var editButton = $('.leaflet-draw-edit-edit')[0];
  if (!editButton) {
    setTimeout(enableMapEditMode, 500);
  } else {
    var clickEvent = new MouseEvent('click');
    editButton.dispatchEvent(clickEvent);
  }
}

function saveOnMapEditMode() {
  var saveButton = $('.leaflet-draw-actions-top li:first-child a')[0];
  if (saveButton) {
    var clickEvent = new MouseEvent('click');
    saveButton.dispatchEvent(clickEvent);
  }
}
<|endoftext|>


<commit_before>var Util, DOM;

(function (Util, DOM) {
    'use strict';

    var DOMProto    = Object.getPrototypeOf(DOM);

    DOMProto.load   = new LoaderProto(Util, DOM.Images, DOM.Events);

    function LoaderProto(Util, Images, Events) {
        /**
         * Функция создаёт элемент и загружает файл с src.
         *
         * @param pParams_o = {
         * name, - название тэга
         * src', - путь к файлу
         * func, - обьект, содержаий одну из функций
         *          или сразу две onload и onerror
         *          {onload: function() {}, onerror: function();}
         * style,
         * id,
         * element,
         * async, - true by default
         * inner: 'id{color:red, },
         * class,
         * notAppend - false by default
         * }
         */
        function load (params) {
            var element, type,
                p           = params,
                func        = p.func,
                name        = p.name,
                parent      = p.parent || document.body,

                /*
                 * if passed arguments function
                 * then it's onload by default
                 *
                 * if object - then onload and onerror
                 */
                funcLoad     = function() {
                    var callback = func && func.onload || func;

                    Events.remove('error', element, funcError);

                    Util.exec(callback);
                },

                funcError    = function() {
                    var callback,
                        template    = 'file {{ src }} could not be loaded',
                        isQuit      = true,
                        msg         = Util.render(template, {
                            src: p.src
                        }),

                        error       = new Error(msg);

                    if (func)
                        callback = func.onerror || func.onload || func;

                    parent.removeChild(element);

                    Images.showError(msg, isQuit);

                    Util.exec(callback, error);
                };

            /* убираем путь к файлу, оставляя только название файла */
            if (!p.id && p.src)
                p.id = load.getIdBySrc(p.src);

            element = document.getElementById(p.id);

            if (element) {
                Util.exec(func);
            } else {
                element                 = document.createElement(name);

                if (name === 'script' || name === 'link')
                    Events.addOnce('load', element, funcLoad)
                          .addError(element, funcError);

                if (p.id)
                    element.id          = p.id;

                if (p.className)
                    element.className   = p.className;

                if (p.src) {
                    /* if work with css use href */
                    if (name === 'link') {
                        element.href    = p.src;
                        element.rel     = 'stylesheet';
                    } else
                        element.src     = p.src;
                }

                if (p.attribute) {
                    type = Util.getType(p.attribute);

                    switch(type) {
                    case 'string':
                        element.setAttribute(p.attribute, '');
                        break;

                    case 'object':
                        Object.keys(p.attribute).forEach(function(name) {
                            element.setAttribute(name, p.attribute[name]);
                        });
                        break;
                    }
                }

                if (p.style)
                    element.style.cssText = p.style;

                if (p.async && name === 'script' || p.async === undefined)
                    element.async = true;

                if (!p.notAppend)
                    parent.appendChild(element);

                if (p.inner)
                    element.innerHTML = p.inner;
            }

            return element;
        }

        /**
         * Function gets id by src
         * @param pSrc
         *
         * Example: http://domain.com/1.js -> 1_js
         */
        load.getIdBySrc             = function(src) {
            var num, sub, id,
                isStr       = Util.isString(src);

            if (isStr) {
                num    = src.lastIndexOf('/') + 1,
                sub    = src.substr(src, num),
                id     = Util.rmStrOnce(src, sub);

                /* убираем точки */
                while (id.indexOf('.') > 0)
                    id = id.replace('.', '-');
            }

            return id;
        };

        /**
         * load file countent via ajax
         *
         * @param pParams
         */
        load.ajax                    = function(params) {
            var data,
                p           = params, countProgress,
                isObject    = Util.isObject(p.data),
                isArray     = Util.isArray(p.data),
                type        = p.type || p.method || 'GET',
                xhr         = new XMLHttpRequest();

            xhr.open(type, p.url, true);

            if (p.responseType)
                xhr.responseType = p.responseType;

            if (isObject || isArray)
                data    = Util.stringifyJSON(p.data);
            else
                data    = p.data;

            Events.add('progress', xhr.upload, function(event) {
                var percent, count;

                if (event.lengthComputable) {
                    percent = (event.loaded / event.total) * 100;
                    count   = Math.round(percent);

                    if (countProgress)
                        Images.setProgress(count);

                    countProgress = true;
                }

            });

            Events.add('readystatechange', xhr, function(event) {
                var TYPE_JSON, type, data, isContain,
                    xhr         = event.target;

                if (xhr.readyState === 4 /* Complete */) {
                    Images.clearProgress();
                    TYPE_JSON   = 'application/json';
                    type        = xhr.getResponseHeader('content-type');

                    if (xhr.status === 200 /* OK */) {
                        data        = xhr.response;
                        isContain   = Util.isContainStr(type, TYPE_JSON);

                        if (p.dataType !== 'text')
                            /* If it's json - parse it as json */
                            if (type && isContain)
                                data = Util.parseJSON(xhr.response) || xhr.response;

                            Util.exec(p.success, data, xhr.statusText, xhr);
                    }
                    /* file not found or connection lost */
                    else {
                        /* if html given or something like thet
                         * getBack just status of result
                         */
                        if (type && type.indexOf('text/plain') !== 0)
                            xhr.responseText = xhr.statusText;

                        Util.exec(p.error, xhr);
                    }
                }
            });

            xhr.send(data);
        };

        load.ext                    = function(src, func) {
            var element,
                ext     =  Util.getExt(src);

            switch (ext) {
            case '.js':
                element = load.js(src, func);
                break;

            case '.css':
                element = load.css(src, func);
                break;

            default:
                element = load({
                    src     : src,
                    func    : func
                });
            }

            return element;
        };

        /**
         * create elements and load them to DOM-tree
         * one-by-one
         *
         * @param params
         * @param callback
         */
        load.series                 = function(params, callback) {
            var funcs   = [];

            if (params) {
                funcs = params.map(function(url) {
                    return load.ext.bind(null, url);
                })
                .concat(callback);

                Util.exec.series(funcs);
            }

            return load;
        };

        /**
         * improve callback of funcs so
         * we pop number of function and
         * if it's last we call pCallBack
         *
         * @param params
         * @param callback - onload function
         */
        load.parallel               = function(params, callback) {
            var funcs   = [];

            if (params) {
                funcs = params.map(function(url) {
                    return load.ext.bind(null, url);
                });

                Util.exec.parallel(funcs, callback);
            }

            return load;
        };

        /**
         * Функция загружает js-файл
         *
         * @param pSrc
         * @param pFunc
         */
        load.js                  = function(src, func) {
            var element = load({
                name : 'script',
                src  : src,
                func : func
            });

            return element;
        },

        load.css                = function(src, callback) {
            var element = load({
                name    : 'link',
                src     : src,
                parent  : document.head,
                func    : callback
            });

            return element;
        };

        /**
         * Функция создаёт елемент style и записывает туда стили
         * @param pParams_o - структура параметров, заполняеться таким
         * образом: {src: ' ',func: '', id: '', element: '', inner: ''}
         * все параметры опциональны
         */
        load.style                  = function(params) {
            if (!params.name)
                params.name      = 'style';

            if (!params.parent)
                params.parent    = document.head;

            return load(params);
        };

        return load;
    }
})(Util, DOM);
<commit_msg>feature(load) add "-join" if ":" in name<commit_after>var Util, DOM;

(function (Util, DOM) {
    'use strict';

    var DOMProto    = Object.getPrototypeOf(DOM);

    DOMProto.load   = new LoaderProto(Util, DOM.Images, DOM.Events);

    function LoaderProto(Util, Images, Events) {
        /**
         * Функция создаёт элемент и загружает файл с src.
         *
         * @param pParams_o = {
         * name, - название тэга
         * src', - путь к файлу
         * func, - обьект, содержаий одну из функций
         *          или сразу две onload и onerror
         *          {onload: function() {}, onerror: function();}
         * style,
         * id,
         * element,
         * async, - true by default
         * inner: 'id{color:red, },
         * class,
         * notAppend - false by default
         * }
         */
        function load (params) {
            var element, type,
                p           = params,
                func        = p.func,
                name        = p.name,
                parent      = p.parent || document.body,

                /*
                 * if passed arguments function
                 * then it's onload by default
                 *
                 * if object - then onload and onerror
                 */
                funcLoad     = function() {
                    var callback = func && func.onload || func;

                    Events.remove('error', element, funcError);

                    Util.exec(callback);
                },

                funcError    = function() {
                    var callback,
                        template    = 'file {{ src }} could not be loaded',
                        isQuit      = true,
                        msg         = Util.render(template, {
                            src: p.src
                        }),

                        error       = new Error(msg);

                    if (func)
                        callback = func.onerror || func.onload || func;

                    parent.removeChild(element);

                    Images.showError(msg, isQuit);

                    Util.exec(callback, error);
                };

            /* убираем путь к файлу, оставляя только название файла */
            if (!p.id && p.src)
                p.id = load.getIdBySrc(p.src);

            element = document.getElementById(p.id);

            if (element) {
                Util.exec(func);
            } else {
                element                 = document.createElement(name);

                if (name === 'script' || name === 'link')
                    Events.addOnce('load', element, funcLoad)
                          .addError(element, funcError);

                if (p.id)
                    element.id          = p.id;

                if (p.className)
                    element.className   = p.className;

                if (p.src) {
                    /* if work with css use href */
                    if (name === 'link') {
                        element.href    = p.src;
                        element.rel     = 'stylesheet';
                    } else
                        element.src     = p.src;
                }

                if (p.attribute) {
                    type = Util.getType(p.attribute);

                    switch(type) {
                    case 'string':
                        element.setAttribute(p.attribute, '');
                        break;

                    case 'object':
                        Object.keys(p.attribute).forEach(function(name) {
                            element.setAttribute(name, p.attribute[name]);
                        });
                        break;
                    }
                }

                if (p.style)
                    element.style.cssText = p.style;

                if (p.async && name === 'script' || p.async === undefined)
                    element.async = true;

                if (!p.notAppend)
                    parent.appendChild(element);

                if (p.inner)
                    element.innerHTML = p.inner;
            }

            return element;
        }

        /**
         * Function gets id by src
         * @param pSrc
         *
         * Example: http://domain.com/1.js -> 1_js
         */
        load.getIdBySrc             = function(src) {
            var num, sub, id,
                isStr       = Util.isString(src);

            if (isStr) {
                if (~src.indexOf(':'))
                    src += '-join';

                num    = src.lastIndexOf('/') + 1,
                sub    = src.substr(src, num),
                id     = Util.rmStrOnce(src, sub);

                /* убираем точки */
                while (id.indexOf('.') > 0)
                    id = id.replace('.', '-');
            }

            return id;
        };

        /**
         * load file countent via ajax
         *
         * @param pParams
         */
        load.ajax                    = function(params) {
            var data,
                p           = params, countProgress,
                isObject    = Util.isObject(p.data),
                isArray     = Util.isArray(p.data),
                type        = p.type || p.method || 'GET',
                xhr         = new XMLHttpRequest();

            xhr.open(type, p.url, true);

            if (p.responseType)
                xhr.responseType = p.responseType;

            if (isObject || isArray)
                data    = Util.stringifyJSON(p.data);
            else
                data    = p.data;

            Events.add('progress', xhr.upload, function(event) {
                var percent, count;

                if (event.lengthComputable) {
                    percent = (event.loaded / event.total) * 100;
                    count   = Math.round(percent);

                    if (countProgress)
                        Images.setProgress(count);

                    countProgress = true;
                }

            });

            Events.add('readystatechange', xhr, function(event) {
                var TYPE_JSON, type, data, isContain,
                    xhr         = event.target;

                if (xhr.readyState === 4 /* Complete */) {
                    Images.clearProgress();
                    TYPE_JSON   = 'application/json';
                    type        = xhr.getResponseHeader('content-type');

                    if (xhr.status === 200 /* OK */) {
                        data        = xhr.response;
                        isContain   = Util.isContainStr(type, TYPE_JSON);

                        if (p.dataType !== 'text')
                            /* If it's json - parse it as json */
                            if (type && isContain)
                                data = Util.parseJSON(xhr.response) || xhr.response;

                            Util.exec(p.success, data, xhr.statusText, xhr);
                    }
                    /* file not found or connection lost */
                    else {
                        /* if html given or something like thet
                         * getBack just status of result
                         */
                        if (type && type.indexOf('text/plain') !== 0)
                            xhr.responseText = xhr.statusText;

                        Util.exec(p.error, xhr);
                    }
                }
            });

            xhr.send(data);
        };

        load.ext                    = function(src, func) {
            var element,
                ext     =  Util.getExt(src);

            switch (ext) {
            case '.js':
                element = load.js(src, func);
                break;

            case '.css':
                element = load.css(src, func);
                break;

            default:
                element = load({
                    src     : src,
                    func    : func
                });
            }

            return element;
        };

        /**
         * create elements and load them to DOM-tree
         * one-by-one
         *
         * @param params
         * @param callback
         */
        load.series                 = function(params, callback) {
            var funcs   = [];

            if (params) {
                funcs = params.map(function(url) {
                    return load.ext.bind(null, url);
                })
                .concat(callback);

                Util.exec.series(funcs);
            }

            return load;
        };

        /**
         * improve callback of funcs so
         * we pop number of function and
         * if it's last we call pCallBack
         *
         * @param params
         * @param callback - onload function
         */
        load.parallel               = function(params, callback) {
            var funcs   = [];

            if (params) {
                funcs = params.map(function(url) {
                    return load.ext.bind(null, url);
                });

                Util.exec.parallel(funcs, callback);
            }

            return load;
        };

        /**
         * Функция загружает js-файл
         *
         * @param pSrc
         * @param pFunc
         */
        load.js                  = function(src, func) {
            var element = load({
                name : 'script',
                src  : src,
                func : func
            });

            return element;
        },

        load.css                = function(src, callback) {
            var element = load({
                name    : 'link',
                src     : src,
                parent  : document.head,
                func    : callback
            });

            return element;
        };

        /**
         * Функция создаёт елемент style и записывает туда стили
         * @param pParams_o - структура параметров, заполняеться таким
         * образом: {src: ' ',func: '', id: '', element: '', inner: ''}
         * все параметры опциональны
         */
        load.style                  = function(params) {
            if (!params.name)
                params.name      = 'style';

            if (!params.parent)
                params.parent    = document.head;

            return load(params);
        };

        return load;
    }
})(Util, DOM);
<|endoftext|>


<commit_before>var express           = require('express')
  , responseTime      = require('response-time')
  , bodyParser        = require('body-parser')
  , _                 = require('underscore')
  , stringify         = require('json-stringify-safe')
  , core              = require('./io/core')
  , config            = require('config')
  , stdout            = require('./stdout')
  ;

var io_core           = require('./io/core')
  , io_code           = require('./io/code')
  ;

function Worker(options) {
  this.options = options || {};

  this.Code = this.options.Code;

  if (!_.isFunction(this.Code)) {
    // throw new Error('A Code constructor was not passed to worker base class');
  }

  this.app = express();
  this.http = require('http').Server(this.app);
  this.io = require('socket.io')(this.http, {
      pingInterval  : 6 * 1000
    , pingTimeout   : 17 * 1000
  });

  var me = this;
  this.io.on('connection', function(socket){
    socket.on('request', function(data, cb){
      me.reqs[data.id] = data;
      cb();
    });
  });

  this.set_routes();
  this.set_middleware();
}

Worker.prototype.set_routes = function(){
  var me = this;

  this.app.all('/execute', function(req, res, next){
    var id    = req.headers['x-tm-id']
      , data  = me.reqs[id]
      ;

    if (data) {
      delete me.reqs[id];

      io_code.run.call(this, me, data, req, res, next);
    } else {
      core.error(new Error('data id not found: ' + id), req, res);
    }
  });

  this.app.get('/', io_code.stats);

  this.app.post('/SIGKILL', io_core.sigkill);
};

Worker.prototype.set_middleware = function(){
  this.app.use(responseTime({
    header : 'x-tm-response-time-worker'
  }));

  this.app.use(io_core.catchall);
  this.app.use(io_core.error);
};

Worker.prototype.reqs = {};

Worker.prototype.stdout = function(id){
  var param = _.rest(arguments);
  this.io.emit('stdout', id, stdout.toString.apply(this, param) + '\n');
};

Worker.prototype.stderr = function(id){
  var param = _.rest(arguments);
  this.io.emit('stderr', id, stdout.toString.apply(this, param) + '\n');
};

Worker.prototype.listen = function(options, cb) {
  options = options || {};

  options.port = options.port || config.port || 80;

  this.http.listen(options.port, function(err, res){
    cb && cb(err, res);
  });
};

module.exports = Worker;<commit_msg>replace full express usage with slimed version<commit_after>var _                 = require('underscore')
  // , express           = require('express')
  , express_req       = require(__dirname + '/../node_modules/express/lib/request')
  , express_res       = require(__dirname + '/../node_modules/express/lib/response')
  , socket_io         = require('socket.io')
  , http              = require('http')
  , responseTime      = require('response-time')
  , bodyParser        = require('body-parser')
  , stringify         = require('json-stringify-safe')
  , core              = require('./io/core')
  , config            = require('config')
  , stdout            = require('./stdout')
  ;

var io_core           = require('./io/core')
  , io_code           = require('./io/code')
  ;

function Worker(options) {
  this.options = options || {};

  this.Code = this.options.Code;

  if (!_.isFunction(this.Code)) {
    throw new Error('A Code constructor was not passed to worker base class');
  }

  // this.app = express();
  var response_time = responseTime({ header : 'x-tm-response-time-worker' });

  var me = this;

  this.http = http.Server(function(req, res) {
    var app = {
        get : function(){}
      , req : req
      , res : res
    };

    req.__proto__ = express_req;
    res.__proto__ = express_res;

    _.extend(req, {
        app       : app
      , res       : res
    });

    _.extend(res, {
        app       : app
      , req       : req
    });

    var next = function(err) {
      core.error(err, req, res);
    }

    response_time(req, res, function() {
      if (req.url.match(/^\/execute$/g)) {
        var id    = req.headers['x-tm-id']
          , data  = me.reqs[id]
          ;

        if (data) {
          delete me.reqs[id];

          io_code.run.call(this, me, data, req, res, next);
        } else {
          core.error(new Error('data id not found: ' + id), req, res);
        }
      }
      else if (req.url.match(/^\/$/g)) {
        io_code.stats(req, res);
      }
      else if (req.url.match(/^\/SIGKILL$/g)) {
        io_core.sigkill(req, res);
      }
    });
  });

  this.io = socket_io(this.http, {
      pingInterval  : 6 * 1000
    , pingTimeout   : 17 * 1000
  });

  var me = this;
  this.io.on('connection', function(socket){
    socket.on('request', function(data, cb){
      me.reqs[data.id] = data;
      cb();
    });
  });

  // this.set_routes();
  // this.set_middleware();
}

// Worker.prototype.set_routes = function(){
//   var me = this;

//   this.app.all('/execute', function(req, res, next){
//     var id    = req.headers['x-tm-id']
//       , data  = me.reqs[id]
//       ;

//     if (data) {
//       delete me.reqs[id];

//       io_code.run.call(this, me, data, req, res, next);
//     } else {
//       core.error(new Error('data id not found: ' + id), req, res);
//     }
//   });

//   this.app.get('/', io_code.stats);

//   this.app.post('/SIGKILL', io_core.sigkill);
// };

// Worker.prototype.set_middleware = function(){
//   // this.app.use(responseTime({
//   //   header : 'x-tm-response-time-worker'
//   // }));

//   // this.app.use(io_core.catchall);
//   // this.app.use(io_core.error);
// };

Worker.prototype.reqs = {};

Worker.prototype.stdout = function(id){
  var param = _.rest(arguments);
  this.io.emit('stdout', id, stdout.toString.apply(this, param) + '\n');
};

Worker.prototype.stderr = function(id){
  var param = _.rest(arguments);
  this.io.emit('stderr', id, stdout.toString.apply(this, param) + '\n');
};

Worker.prototype.listen = function(options, cb) {
  options = options || {};

  options.port = options.port || config.port || 80;

  this.http.listen(options.port, function(err, res){
    cb && cb(err, res);
  });
};

module.exports = Worker;<|endoftext|>


<commit_before>$(function() {

    var newBoard = new Board("Kanban", 4);
    var errorMsg;

    var columnToDo = new Column("To Do", 5);
    var columnInProgress = new Column("In Progress", 5);
    var columnReview = new Column("Review", 5);
    var columnDone = new Column("Done", 5);

    var localStorageKanban = new LocalStore();

    var columns = [columnToDo, columnInProgress, columnReview, columnDone];

    for (var i = 0; i < columns.length; i++) {
        newBoard.addOneColumnsToBoard(columns[i]);
    }

    var retrieveTicketsToDo = localStorageKanban.retrieveData("To_Do");
    var retrieveTicketsInProgress = localStorageKanban.retrieveData("In_Progress");
    var retrieveTicketsReview = localStorageKanban.retrieveData("Review");
    var retrieveTicketsDone = localStorageKanban.retrieveData("Done");

    function localDataUpdate(itemName, column) {
        localStorageKanban.updateStorage( itemName, column.showAllTicket() );
    }

    function initRetrievedDataRender(retrievedData, itemName, column) {

        if (retrievedData === null) {
            localStorageKanban.updateStorage( itemName, column.showAllTicket() );
            retrievedData = localStorageKanban.retrieveData(itemName);
        }

        for (var i = 0; i < retrievedData.length; i++ ) {
            var title = retrievedData[i].title;
            var description = retrievedData[i].description;
            var newTicket = new Ticket(title, description);
            column.addOneTicket(newTicket);
        }

        ticketRender(column);

        var bgImgURL = localStorageKanban.retrieveData("bgImgURL");
        if (bgImgURL) {
            document.getElementsByClassName("board")[0].style.backgroundImage = "url('"+ bgImgURL +"')";
        }
    }

    var dAndD = new function() {
        var draggedTicketTitle;

        this.allowDrop = function(event) {
            event.preventDefault();
        };

        this.drag = function(event) {
            draggedTicketTitle = $(event.target).find("span").text();
        };

        this.drop = function(event, moveTicketFunc, ticketRenderFunc) {
            event.preventDefault();
            var file = event.dataTransfer.files[0];
            if (!file) {
                var $target = $(event.target);
                var destinationColumnTitle = $target.siblings("header").find("span").text();
                moveTicketFunc(draggedTicketTitle, destinationColumnTitle, ticketRenderFunc);
                $("#errorMsg").text(errorMsg).fadeIn(200);
            }
        };

        this.bin = function(event, deleteTicketFunc, ticketRenderFunc) {
            deleteTicketFunc(draggedTicketTitle, ticketRenderFunc);
            $("#errorMsg").text(errorMsg).fadeIn(200);
        };
    };

    var bgImgAction = new function() {

        function loaded(event) {
            var dataURL = event.target.result;
            document.getElementsByClassName("board")[0].style.backgroundImage = "url('"+ dataURL +"')";

            localStorageKanban.updateStorage("bgImgURL", dataURL);
        }

        this.imgDropAndDisplay = function(event) {
            event.preventDefault(); // Cancel the default browser action.
            var file = event.dataTransfer.files[0];
            var reader = new FileReader();
            if (file) {
                reader.readAsDataURL(file);
                reader.onload = loaded;
            }
        };

        this.imgSelectAndDisplay= function(event) { //inspiration ref: http://www.html5rocks.com/en/tutorials/file/dndfiles/#toc-selecting-files-dnd
            var file = event.target.files[0];
            var reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = loaded;
        };

    };

    function boardRender() {
        var boardName = newBoard.getBoardName();
        var cssClass = newBoard.constructor.name.toLowerCase();
        var $newDiv = $('
',{ id: boardName, "class": cssClass});
        $("#board_container").append($newDiv);
        var theBoard = $newDiv.get(0);
        theBoard.addEventListener("drop", bgImgAction.imgDropAndDisplay, false);
        theBoard.addEventListener("dragover", dAndD.allowDrop);
    }

    function columnRender(boardName) {
        var arrayOfColumns = newBoard.getAllColumns();
        for (var i = 0; i < newBoard.getColumnCount(); i++) {
            var columnTitle = arrayOfColumns[i].getTitle();
            var divId = columnTitle.replace(/ /g,'_');
            var cssClass = arrayOfColumns[i].constructor.name.toLowerCase();
            var $newDiv = $('
',{ id: divId, "class": cssClass});
            $newDiv.append(""+ columnTitle +" ("+ arrayOfColumns[i].getWipNumber() +")

");
            $("#"+boardName).append($newDiv);
            //find child element javascript
            var theColumn = $newDiv.get(0);
            theColumn.getElementsByTagName("section")[0].addEventListener("dragover", dAndD.allowDrop, false);
            theColumn.getElementsByTagName("section")[0].addEventListener("drop", function() {
                dAndD.drop(event, moveTicket, ticketRender);
            }, false);
        }
    }

    function createATicket(ticketTitle, ticketDescription, destinationColumn, ticketRenderFunc) {

        var ticketExists = newBoard.checkIfATicketExistOnBoard(ticketTitle);
        var reachedWipOrNot = destinationColumn.reachedWipOrNot();
        if (!reachedWipOrNot) {
            if (!ticketExists) {
                var newTicket = new Ticket(ticketTitle, ticketDescription);
                destinationColumn.addOneTicket(newTicket);
                var newSimpleTicket = newTicket.toSimpleTicket();

                //localStorage
                retrieveTicketsToDo = localStorageKanban.retrieveData("To_Do");
                localStorageKanban.addToArray(retrieveTicketsToDo, newSimpleTicket);
                localStorageKanban.updateStorage("To_Do", retrieveTicketsToDo);
                //localStorage

                ticketRenderFunc(destinationColumn);
                errorMsg = "";
            } else {
                errorMsg = "Ticket already exists.";
                console.log("Ticket already exists.");
            }
        } else {
            errorMsg = "destination column reached WIP.";
            console.log("reached WIP.");
        }
        //1. create a ticket with Title and Description
        //2. set a destination column and add it to the array in that column
        //3. render the column that has the ticket
    }

    function ticketRender(column) {
        var whichColumn = column.getTitle().replace(/ /g, '_');
        var $board = $("#" + whichColumn);
        $board.find("section").html("");
        var arrayOfTickets = column.showAllTicket();
        if ( arrayOfTickets.length > 0 ) {
            for (var i = 0; i < column.getTicketCount(); i++) {
                var ticketTitle = arrayOfTickets[i].getTitle();
                var ticketDescription = arrayOfTickets[i].getDescription();
                var cssClass = arrayOfTickets[i].constructor.name.toLowerCase();
                var $newDiv = $('
', {"class": cssClass,
                                            "draggable": "true"
                                            });
                $newDiv.html("Title: "+ ticketTitle +"
Description: "+ ticketDescription);
                $board.find("section").append($newDiv);
                var newDiv = $newDiv.get(0);//
                newDiv.addEventListener("dragstart", dAndD.drag, false);
            }
        }
    }

    function moveTicket(ticketTitle, columnTitle, ticketRenderFunc) {
        //1. check if ticket exists.
        var ticketExists = newBoard.checkIfATicketExistOnBoard(ticketTitle); // need ticketTitle
        if (ticketExists) {
            //2. find the column
            var columnOrigin = newBoard.findColumnByTicketTitle(ticketTitle);
            var ticketFound = columnOrigin.findTicketByTitle(ticketTitle);
            var columnFound = newBoard.findColumnByTitle(columnTitle); // need columnTitle
            var newSimpleTicket = ticketFound.toSimpleTicket();
            if (columnFound) {
                //check if reached Wip or not
                if ( !columnFound.reachedWipOrNot() ) {
                    //3. move the ticketFound to the columnFound
                    columnFound.addOneTicket(ticketFound);
                    columnOrigin.removeTicketByTitle(ticketTitle);
                    ticketRenderFunc(columnOrigin);
                    ticketRenderFunc(columnFound);

                    //localStorage
                    ///Origin
                    var columnNameForLocalStorageOrigin = columnOrigin.getTitle().replace(/ /g, '_');
                    ////retrieve
                    var retrieveDataO = localStorageKanban.retrieveData(columnNameForLocalStorageOrigin);
                    ////remove
                    localStorageKanban.removeDataInArray(retrieveDataO, ticketTitle);
                    ////update
                    localStorageKanban.updateStorage(columnNameForLocalStorageOrigin, retrieveDataO);

                    ///Found
                    var columnNameForLocalStorageFound = columnFound.getTitle().replace(/ /g, '_');
                    ////retrieve
                    var retrieveDataF = localStorageKanban.retrieveData(columnNameForLocalStorageFound);
                    ////add
                    localStorageKanban.addToArray(retrieveDataF, newSimpleTicket);
                    ////update
                    localStorageKanban.updateStorage(columnNameForLocalStorageFound, retrieveDataF);
                    //localStorage

                    errorMsg = "";
                } else {
                    errorMsg = "destination column reached WIP.";
                    console.log("reached WIP.");
                }
            } else {
                errorMsg = "Cannot find such column.";
                console.log("Cannot find such column.");
            }
        } else {
            errorMsg = "Ticket not found.";
            console.log("Ticket not found.");
        }
    }

    function deleteTicket(ticketTitle, ticketRenderFunc) {
        var ticketExists = newBoard.checkIfATicketExistOnBoard(ticketTitle);
        if (ticketExists) {
            var columnOrigin = newBoard.findColumnByTicketTitle(ticketTitle);
            if (columnOrigin.getTitle() === columnDone.getTitle()) {
                columnDone.removeTicketByTitle(ticketTitle);
                ticketRenderFunc(columnDone);
                errorMsg = "";

                //localStorage
                var columnNameForLocalStorageOrigin = columnOrigin.getTitle().replace(/ /g, '_'); //"Done"
                ///retrieve
                var retrieveDataO = localStorageKanban.retrieveData(columnNameForLocalStorageOrigin);
                ///remove
                localStorageKanban.removeDataInArray(retrieveDataO, ticketTitle);
                ////update
                localStorageKanban.updateStorage(columnNameForLocalStorageOrigin, retrieveDataO);
                //localStorage

                animatedBin();
            } else {
                errorMsg = "Ticket can only be deleted from Done.";
                console.log("Ticket can only be deleted from Done.");
            }
        } else {
            errorMsg = "Ticket not found.";
            console.log("Ticket not found.");
        }
    }

    boardRender();
    columnRender("Kanban");

    initRetrievedDataRender(retrieveTicketsToDo, "To_Do", columnToDo);
    initRetrievedDataRender(retrieveTicketsInProgress, "In_Progress", columnInProgress);
    initRetrievedDataRender(retrieveTicketsReview, "Review", columnReview);
    initRetrievedDataRender(retrieveTicketsDone, "Done", columnDone);

    $("#create_a_ticket").on("click", function(event) {
        event.preventDefault();

        var title = $("input[name='ticket_title']").val();
        var description = $("input[name='ticket_description']").val();

        if (title.length != 0 && description != 0) {
            createATicket(title, description, columnToDo, ticketRender);
            $("input:text").val("");
        } else {
            errorMsg = "Please enter title and description.";
        }
        $("#errorMsg").text(errorMsg).fadeIn(200);
    });

    $("#move_ticket").on("click", function(event) {
        event.preventDefault();
        var ticketTitle = $("input[name='ticket_title']").val();
        var columnTitle = $("input[name='column_title']").val();
        moveTicket(ticketTitle, columnTitle, ticketRender);
        $("#errorMsg").text(errorMsg).fadeIn(200);
    });

    $("#delete_ticket").on("click", function(event) {
        event.preventDefault();
        var ticketTitle = $("input[name='ticket_title']").val();
        deleteTicket(ticketTitle, ticketRender);
        $("#errorMsg").text(errorMsg).fadeIn(200);
    });

    $("#clear_ticket").on("click", function(event) {
        event.preventDefault();

        for (var i = 0; i < columns.length; i++) {
             columns[i].removeAllTickets();
             ticketRender(columns[i]);
        }

        localStorageKanban.deleteStorageItem("To_Do");
        localStorageKanban.deleteStorageItem("In_Progress");
        localStorageKanban.deleteStorageItem("Review");
        localStorageKanban.deleteStorageItem("Done");

        localDataUpdate("To_Do", columnToDo);
        localDataUpdate("In_Progress", columnInProgress);
        localDataUpdate("Review", columnReview);
        localDataUpdate("Done", columnDone);
    });

    $("#dltBgImg").on("click", function() {
        localStorageKanban.deleteStorageItem("bgImgURL");
        document.getElementsByClassName("board")[0].style.backgroundImage = "none";
    });

    $("#selectFiles").on("change", bgImgAction.imgSelectAndDisplay);

    //bin
    document.getElementById("bin").addEventListener("dragover", dAndD.allowDrop, false);
    document.getElementById("bin").addEventListener("drop", function() {
        dAndD.bin(event, deleteTicket, ticketRender);
    }, false);

    function animatedBin() {
        var $bin = $( document.getElementById("icon_bin") );

        setTimeout(function(){
            $bin.css({
                "transform": "rotate(-30deg)"
            });
        }, 0);
        setTimeout(function(){
            $bin.css({
                "transform": "rotate(20deg)"
            });
        }, 100);
        setTimeout(function(){
            $bin.css({
                "transform": "rotate(-20deg)"
            });
        }, 200);
        setTimeout(function(){
            $bin.css({
                "transform": "rotate(20deg)"
            });
        }, 300);
        setTimeout(function(){
            $bin.css({
                "transform": "none"
            });
        }, 400);
    }

    //// console logs
    console.log(retrieveTicketsToDo);
    console.log(retrieveTicketsInProgress);
    console.log(retrieveTicketsReview);
    console.log(retrieveTicketsDone);

});
<commit_msg>refactored<commit_after>$(function() {

    var newBoard = new Board("Kanban", 4);
    var errorMsg;

    var columnToDo = new Column("To Do", 5);
    var columnInProgress = new Column("In Progress", 5);
    var columnReview = new Column("Review", 5);
    var columnDone = new Column("Done", 5);

    var localStorageKanban = new LocalStore();

    var columns = [columnToDo, columnInProgress, columnReview, columnDone];

    var storageItemNames = ["To_Do", "In_Progress", "Review", "Done"];

    var retrieveTicketsToDo = localStorageKanban.retrieveData(storageItemNames[0]);
    var retrieveTicketsInProgress = localStorageKanban.retrieveData(storageItemNames[1]);
    var retrieveTicketsReview = localStorageKanban.retrieveData(storageItemNames[2]);
    var retrieveTicketsDone = localStorageKanban.retrieveData(storageItemNames[3]);

    var retrievedDataArrays = [retrieveTicketsToDo, retrieveTicketsInProgress, retrieveTicketsReview, retrieveTicketsDone];

    for (var i = 0; i < columns.length; i++) {
        newBoard.addOneColumnsToBoard(columns[i]);
    }

    function showErrorMsg() {
        $("#errorMsg").text(errorMsg).fadeIn(200);
    }

    function localDataUpdate(itemName, column) {
        localStorageKanban.updateStorage( itemName, column.showAllTicket() );
    }

    function initRetrievedDataRender(retrievedData, itemName, column) {

        if (retrievedData === null) {
            localStorageKanban.updateStorage( itemName, column.showAllTicket() );
            retrievedData = localStorageKanban.retrieveData(itemName);
        }

        for (var i = 0; i < retrievedData.length; i++ ) {
            var title = retrievedData[i].title;
            var description = retrievedData[i].description;
            var newTicket = new Ticket(title, description);
            column.addOneTicket(newTicket);
        }

        ticketRender(column);

        var bgImgURL = localStorageKanban.retrieveData("bgImgURL");
        if (bgImgURL) {
            document.getElementsByClassName("board")[0].style.backgroundImage = "url('"+ bgImgURL +"')";
        }
    }

    var dAndD = new function() {
        var draggedTicketTitle;

        this.allowDrop = function(event) {
            event.preventDefault();
        };

        this.drag = function(event) {
            draggedTicketTitle = $(event.target).find("span").text();
        };

        this.drop = function(event, moveTicketFunc, ticketRenderFunc) {
            event.preventDefault();
            var file = event.dataTransfer.files[0];
            if (!file) {
                var $target = $(event.target);
                var destinationColumnTitle = $target.siblings("header").find("span").text();
                moveTicketFunc(draggedTicketTitle, destinationColumnTitle, ticketRenderFunc);
                showErrorMsg();
            }
        };

        this.bin = function(event, deleteTicketFunc, ticketRenderFunc) {
            deleteTicketFunc(draggedTicketTitle, ticketRenderFunc);
            showErrorMsg();
        };
    };

    var bgImgAction = new function() {

        function loaded(event) {
            var dataURL = event.target.result;
            document.getElementsByClassName("board")[0].style.backgroundImage = "url('"+ dataURL +"')";

            localStorageKanban.updateStorage("bgImgURL", dataURL);
        }

        this.imgDropAndDisplay = function(event) {
            event.preventDefault(); // Cancel the default browser action.
            var file = event.dataTransfer.files[0];
            var reader = new FileReader();
            if (file) {
                reader.readAsDataURL(file);
                reader.onload = loaded;
            }
        };

        this.imgSelectAndDisplay= function(event) { //inspiration ref: http://www.html5rocks.com/en/tutorials/file/dndfiles/#toc-selecting-files-dnd
            var file = event.target.files[0];
            var reader = new FileReader();
            if (file) {
                reader.readAsDataURL(file);
                reader.onload = loaded;
            }
        };

    };

    function boardRender() {
        var boardName = newBoard.getBoardName();
        var cssClass = newBoard.constructor.name.toLowerCase();
        var $newDiv = $('
',{ id: boardName, "class": cssClass});
        $("#board_container").append($newDiv);
        var theBoard = $newDiv.get(0);
        theBoard.addEventListener("drop", bgImgAction.imgDropAndDisplay, false);
        theBoard.addEventListener("dragover", dAndD.allowDrop);
    }

    function columnRender(boardName) {
        var arrayOfColumns = newBoard.getAllColumns();
        for (var i = 0; i < newBoard.getColumnCount(); i++) {
            var columnTitle = arrayOfColumns[i].getTitle();
            var divId = columnTitle.replace(/ /g,'_');
            var cssClass = arrayOfColumns[i].constructor.name.toLowerCase();
            var $newDiv = $('
',{ id: divId, "class": cssClass});
            $newDiv.append(""+ columnTitle +" ("+ arrayOfColumns[i].getWipNumber() +")

");
            $("#"+boardName).append($newDiv);
            //find child element javascript
            var theColumn = $newDiv.get(0);
            theColumn.getElementsByTagName("section")[0].addEventListener("dragover", dAndD.allowDrop, false);
            theColumn.getElementsByTagName("section")[0].addEventListener("drop", function() {
                dAndD.drop(event, moveTicket, ticketRender);
            }, false);
        }
    }

    function ticketRender(column) {
        var whichColumn = column.getTitle().replace(/ /g, '_');
        var $board = $("#" + whichColumn);
        $board.find("section").html("");
        var arrayOfTickets = column.showAllTicket();
        if ( arrayOfTickets.length > 0 ) {
            for (var i = 0; i < column.getTicketCount(); i++) {
                var ticketTitle = arrayOfTickets[i].getTitle();
                var ticketDescription = arrayOfTickets[i].getDescription();
                var cssClass = arrayOfTickets[i].constructor.name.toLowerCase();
                var $newDiv = $('
', {"class": cssClass,
                    "draggable": "true"
                });
                $newDiv.html("Title: "+ ticketTitle +"
Description: "+ ticketDescription);
                $board.find("section").append($newDiv);
                var newDiv = $newDiv.get(0);//
                newDiv.addEventListener("dragstart", dAndD.drag, false);
            }
        }
    }

    function createATicket(ticketTitle, ticketDescription, destinationColumn, ticketRenderFunc) {
        var ticketExists = newBoard.checkIfATicketExistOnBoard(ticketTitle);
        var reachedWipOrNot = destinationColumn.reachedWipOrNot();
        if (!reachedWipOrNot) {
            if (!ticketExists) {
                var newTicket = new Ticket(ticketTitle, ticketDescription);
                destinationColumn.addOneTicket(newTicket);
                var newSimpleTicket = newTicket.toSimpleTicket();

                //localStorage
                retrieveTicketsToDo = localStorageKanban.retrieveData("To_Do");
                localStorageKanban.addToArray(retrieveTicketsToDo, newSimpleTicket);
                localStorageKanban.updateStorage("To_Do", retrieveTicketsToDo);
                //localStorage

                ticketRenderFunc(destinationColumn);
                errorMsg = "";
            } else {
                errorMsg = "Ticket already exists.";
                console.log("Ticket already exists.");
            }
        } else {
            errorMsg = "destination column reached WIP.";
            console.log("reached WIP.");
        }
        //1. create a ticket with Title and Description
        //2. set a destination column and add it to the array in that column
        //3. render the column that has the ticket
    }

    function moveTicket(ticketTitle, columnTitle, ticketRenderFunc) {
        //1. check if ticket exists.
        var ticketExists = newBoard.checkIfATicketExistOnBoard(ticketTitle); // need ticketTitle
        if (ticketExists) {
            //2. find the column
            var columnOrigin = newBoard.findColumnByTicketTitle(ticketTitle);
            var ticketFound = columnOrigin.findTicketByTitle(ticketTitle);
            var columnFound = newBoard.findColumnByTitle(columnTitle); // need columnTitle
            var newSimpleTicket = ticketFound.toSimpleTicket();
            if (columnFound) {
                //check if reached Wip or not
                if ( !columnFound.reachedWipOrNot() ) {
                    //3. move the ticketFound to the columnFound
                    columnFound.addOneTicket(ticketFound);
                    columnOrigin.removeTicketByTitle(ticketTitle);
                    ticketRenderFunc(columnOrigin);
                    ticketRenderFunc(columnFound);

                    //localStorage
                    ///Origin
                    var columnNameForLocalStorageOrigin = columnOrigin.getTitle().replace(/ /g, '_');
                    ////retrieve
                    var retrieveDataO = localStorageKanban.retrieveData(columnNameForLocalStorageOrigin);
                    ////remove
                    localStorageKanban.removeDataInArray(retrieveDataO, ticketTitle);
                    ////update
                    localStorageKanban.updateStorage(columnNameForLocalStorageOrigin, retrieveDataO);

                    ///Found
                    var columnNameForLocalStorageFound = columnFound.getTitle().replace(/ /g, '_');
                    ////retrieve
                    var retrieveDataF = localStorageKanban.retrieveData(columnNameForLocalStorageFound);
                    ////add
                    localStorageKanban.addToArray(retrieveDataF, newSimpleTicket);
                    ////update
                    localStorageKanban.updateStorage(columnNameForLocalStorageFound, retrieveDataF);
                    //localStorage

                    errorMsg = "";
                } else {
                    errorMsg = "destination column reached WIP.";
                    console.log("reached WIP.");
                }
            } else {
                errorMsg = "Cannot find such column.";
                console.log("Cannot find such column.");
            }
        } else {
            errorMsg = "Ticket not found.";
            console.log("Ticket not found.");
        }
    }

    function deleteTicket(ticketTitle, ticketRenderFunc) {
        var ticketExists = newBoard.checkIfATicketExistOnBoard(ticketTitle);
        if (ticketExists) {
            var columnOrigin = newBoard.findColumnByTicketTitle(ticketTitle);
            if (columnOrigin.getTitle() === columnDone.getTitle()) {
                columnDone.removeTicketByTitle(ticketTitle);
                ticketRenderFunc(columnDone);
                errorMsg = "";

                //localStorage
                var columnNameForLocalStorageOrigin = columnOrigin.getTitle().replace(/ /g, '_'); //"Done"
                ///retrieve
                var retrieveDataO = localStorageKanban.retrieveData(columnNameForLocalStorageOrigin);
                ///remove
                localStorageKanban.removeDataInArray(retrieveDataO, ticketTitle);
                ////update
                localStorageKanban.updateStorage(columnNameForLocalStorageOrigin, retrieveDataO);
                //localStorage

                animatedBin();
            } else {
                errorMsg = "Ticket can only be deleted from Done.";
                console.log("Ticket can only be deleted from Done.");
            }
        } else {
            errorMsg = "Ticket not found.";
            console.log("Ticket not found.");
        }
    }

    var inputVal = function() {
        var ticketTitle = $("input[name='ticket_title']").val();
        var description = $("input[name='ticket_description']").val();
        var columnTitle = $("input[name='column_title']").val();

        return {
                ticketTitle: ticketTitle,
                description: description,
                columnTitle: columnTitle
                }
    };

    boardRender();
    columnRender("Kanban");

    for (var s = 0; s < columns.length; s++) {
        initRetrievedDataRender(retrievedDataArrays[s], storageItemNames[s], columns[s]);
    }

    //////buttons
    $("#create_a_ticket").on("click", function(event) {
        event.preventDefault();
        if ( inputVal().ticketTitle.length != 0 && inputVal().description != 0) {
            createATicket( inputVal().ticketTitle, inputVal().description, columnToDo, ticketRender);
            $("input:text").val("");
        } else {
            errorMsg = "Please enter title and description.";
        }
        showErrorMsg();
    });

    $("#move_ticket").on("click", function(event) {
        event.preventDefault();
        moveTicket( inputVal().ticketTitle, inputVal().columnTitle, ticketRender);
        showErrorMsg();
    });

    $("#delete_ticket").on("click", function(event) {
        event.preventDefault();
        deleteTicket( inputVal().ticketTitle, ticketRender);
        showErrorMsg();
    });

    $("#clear_ticket").on("click", function(event) {
        event.preventDefault();

        function storageItemClearAndUpdate(itemName, column) {
            localStorageKanban.deleteStorageItem(itemName);
            localDataUpdate(itemName, column);
        }

        for (var i = 0; i < columns.length; i++) {
            columns[i].removeAllTickets();
            ticketRender(columns[i]);

            storageItemClearAndUpdate(storageItemNames[i], columns[i]);
        }

    });

    $("#dltBgImg").on("click", function() {
        localStorageKanban.deleteStorageItem("bgImgURL");
        document.getElementsByClassName("board")[0].style.backgroundImage = "none";
    });

    $("#selectFiles").on("change", bgImgAction.imgSelectAndDisplay);

    ///////interactive bin
    document.getElementById("bin").addEventListener("dragover", dAndD.allowDrop, false);
    document.getElementById("bin").addEventListener("drop", function() {
        dAndD.bin(event, deleteTicket, ticketRender);
    }, false);

    function animatedBin() {
        var $bin = $( document.getElementById("icon_bin") );

        setTimeout(function(){
            $bin.css({
                "transform": "rotate(-30deg)"
            });
        }, 0);
        setTimeout(function(){
            $bin.css({
                "transform": "rotate(20deg)"
            });
        }, 100);
        setTimeout(function(){
            $bin.css({
                "transform": "rotate(-20deg)"
            });
        }, 200);
        setTimeout(function(){
            $bin.css({
                "transform": "rotate(20deg)"
            });
        }, 300);
        setTimeout(function(){
            $bin.css({
                "transform": "none"
            });
        }, 400);
    }

    //////console logs
    console.log(retrieveTicketsToDo);
    console.log(retrieveTicketsInProgress);
    console.log(retrieveTicketsReview);
    console.log(retrieveTicketsDone);

});
<|endoftext|>


<commit_before>/**
 * @flow
 */
import path from 'path';
import express from 'express';
import React from 'react';

type RouteFilter = (route: ReactRouterRoute) => bool;

/**
 * A class that parse the react router routes, that also contains express http handlers.
 */
export default class RouteParser {
	_route: ReactRouterRoute;

	/**
	 * A constructor that takes the route that is being parsed.
	 *
	 * @param route	{ReactRouterRoute}	The route to parse
	 *							NOTE:	React routes can have http sub-routes, but http routes can
	 *									not have React sub-routes
	 */
	constructor(route: ReactRouterRoute) {
		this._route = route;
	}

	/**
	 * Gets the react router route without any of the http handler routes.
	 *
	 * @return	{ReactRouterRoute}	The route with out http handlers
	 */
	getReactRouterRoute(): ReactRouterRoute {
		return React.cloneElement(
			this._route,
			{},
			this._getReactRouterRoutesChildren()
		);
	}

	/**
	 * Gets the express router defined in the react router Route.
	 *
	 * @return	{ExpressRouter}		The router that handles all non page load requests
	 */
	getExpressRouter(): ExpressRouter {
		let router = express.Router();
		this._getExpressRouterRoutes().forEach((route) => {
			router.use(getPathOf(route), getRouterFrom(route));
		});
		return router;
	}

	_getExpressRouterRoutes(): Array<ReactRouterRoute> {
		return this._flattenAndFilteredChildren(hasExpressRouterRecursive).filter(hasExpressRouter);
	}

	_getReactRouterRoutesChildren(): Array<ReactRouterRoute> {
		return this._filterRoutesChildren(doesntHaveExpressRouter);
	}

	_filterRoutesChildren(shouldKeep: RouteFilter): Array<ReactRouterRoute> {
		return filterChildren(this._route.props.children, shouldKeep);
	}

	_flattenAndFilteredChildren(shouldKeep: RouteFilter) : Array<ReactRouterRoute> {
		return flattenRoutes(
			getPathOf(this._route),
			this._filterRoutesChildren(shouldKeep)
		);
	}
}

// Helper Functions
function hasExpressRouter(route: ReactRouterRoute): bool {
	return route.type.hasRouter? true: false;
}

function doesntHaveExpressRouter(route: ReactRouterRoute): bool {
	return !hasExpressRouter(route);
}

function hasExpressRouterRecursive(route: ReactRouterRoute): bool {
	if(hasExpressRouter(route)) return true;
	if(!route.props.children) return false;

	// Check if any child has router
	const numberOfChildrenWithRouter = filterChildren(
		route.props.children,
		hasExpressRouterRecursive
	).length;
	return numberOfChildrenWithRouter > 0;
}

function filterChildren(
	children: ?(ReactRouterRoute | Array<ReactRouterRoute>),
	shouldKeep: RouteFilter
): Array<ReactRouterRoute> {
	let filteredChildren = [];
	React.Children.forEach(children, (child, i) => {
		// Don't include null children
		if(!child) return;

		// Filter children and their children by should keep
		if(shouldKeep(child)) {
			filteredChildren.push(
				React.cloneElement(
					child,
					{key: i},
					child.props.children?
						filterChildren(child.props.children, shouldKeep):
						null
				)
			);
		}
	});
	return filteredChildren;
}

function flattenRoutes(
	startPath: string,
	routes: Array<ReactRouterRoute>
): Array<ReactRouterRoute> {
	if(routes.length === 0) return [];

	let flattenedRoutes = [];
	const flattener = (currRoutes, prefix) => {
		//NOTE, Not using React.Children.map because github.com/facebook/react/issues/2872
		React.Children.forEach(currRoutes, (route) => {
			const currPath = getPathOf(route, prefix);

			flattenedRoutes.push(React.cloneElement(route, { path: currPath }));
			if(route.props.children) flattener(route.props.children, currPath);
		});
	};
	flattener(routes, startPath);

	return flattenedRoutes;
}

function getPathOf(route: ReactRouterRoute, prefix?: string): string {
	return path.join(
		prefix? prefix: '/',
		route.props.path? route.props.path: (route.props.name? route.props.name: '')
	);
}

function getRouterFrom(route: ReactRouterRoute): ExpressRouter {
	if(doesntHaveExpressRouter(route)) {
		throw new Error("Routes passed to 'getRouterFrom' must have 'getRouter'.");
	}

	return route.type.getRouter(route.props);
}
<commit_msg>Update RouterParser<commit_after>/**
 * @flow
 */
import path from 'path';
import express from 'express';
import React from 'react';

/**
 * A class that parse the react router routes, that also contains express http handlers.
 */
export default class RouteParser {
	_router: ReactRouterRoute;

	/**
	 * A constructor that takes the route that is being parsed.
	 *
	 * @param route	{ReactRouterRoute}	The route to parse
	 *							NOTE:	React routes can have http sub-routes, but http routes can
	 *									not have React sub-routes
	 */
	constructor(route: ReactRouterRoute) {
		this._router = route;
	}

	/**
	 * Gets the react router route without any of the http handler routes.
	 *
	 * @return	{ReactRouterRoute}	The route with out http handlers
	 */
	getReactRouterRoute(): ReactRouterRoute {
		return filterChildren(this._router, doesntHaveExpressRouter);
	}

	/**
	 * Gets the express router defined in the react router Route.
	 *
	 * @return	{ExpressRouter}		The router that handles all non page load requests
	 */
	getExpressRouter(): ExpressRouter {
		let router = express.Router();
		forEachRoute(this._router, (route, path) => {
			if(hasExpressRouter(route)) router.use(path, getRouterFrom(route));
		});
		return router;
	}
}

/**
 * Get the given route with its children filtered using the given function.
 *
 * NOTE: Does not call render for each element, only get children from el.props.children
 * NOTE: The given route is not sent to the checkFn
 *
 * @param route   The react-router <Route /> to filter the children of
 * @param checkFn The function to check weather or not to keep the child
 *
 * @return        The react-router <Route /> without the filtered out children
 */
export function filterChildren(route: ReactRouterRoute, checkFn: (route: ReactRouterRoute) => bool): ReactRouterRoute {
  const { children } = route.props;
  if(!children) return route;

  return React.cloneElement(
  	route,
  	{},
  	React.Children.toArray(children)
  		.filter(checkFn)
  		.map((child) => filterChildren(child, checkFn))
  );
}

/**
 * Call the given callback for each element in the given react-router <Route />.
 *
 * NOTE: Does not call render for each element, only get children from el.props.children
 *
 * @param route     	The react-router <Route /> to traverse
 * @param mapFn     	The function to call with each route, and its current path in the router
 * @param [currPath]  The path of the given route
 */
export function forEachRoute(
	route: ReactRouterRoute,
	mapFn: (el: ReactRouterRoute,	path: string) => void,
	currPath: string = ''
) {
  mapFn(route, currPath);

  React.Children.forEach(route.props.children, (child) => {
     const nextPath = child.props.path? path.join(currPath, child.props.path): currPath;

     forEachRoute(child, mapFn, nextPath);
  });
}

// Helper Functions
function hasExpressRouter(route: ReactRouterRoute): bool {
	return route.type.hasRouter? true: false;
}

function doesntHaveExpressRouter(route: ReactRouterRoute): bool {
	return !hasExpressRouter(route);
}

function getRouterFrom(route: ReactRouterRoute): ExpressRouter {
	if(doesntHaveExpressRouter(route)) {
		throw new Error("Routes passed to 'getRouterFrom' must have 'getRouter'.");
	}

	return route.type.getRouter(route.props);
}
<|endoftext|>


<commit_before>'use strict';

const CoffeeScript = require('coffeescript');
const vm           = require('vm');
const _            = require('lodash');

module.exports = (coffeeSource, context, scope) => {
  if(!coffeeSource){ return; }
  let src     = CoffeeScript.compile(coffeeSource, {bare: true});
  let script  = new vm.Script(src)

  let ctx = {_: _};

  Object.assign(ctx, context);
  Object.assign(ctx, context.webResponse || {});
  Object.assign(ctx, context.attributes);
  Object.assign(ctx, context.temp);
  Object.assign(ctx, context.slots);

  if(scope){
    Object.assign(ctx, scope);
  }

  let vmContext = new vm.createContext(ctx);

  return script.runInNewContext(vmContext);
}

<commit_msg>Don't crash when evaluating a script.<commit_after>'use strict';

const CoffeeScript = require('coffeescript');
const vm           = require('vm');
const _            = require('lodash');

module.exports = (coffeeSource, context, scope) => {
  if(!coffeeSource){ return; }
  let src     = CoffeeScript.compile(coffeeSource, {bare: true});
  let script  = new vm.Script(src)

  let ctx = {_: _};

  Object.assign(ctx, context);
  Object.assign(ctx, context.webResponse || {});
  Object.assign(ctx, context.attributes);
  Object.assign(ctx, context.temp);
  Object.assign(ctx, context.slots);

  if(scope){
    Object.assign(ctx, scope);
  }

  let vmContext = new vm.createContext(ctx);

  try {
    return script.runInNewContext(vmContext);
  } catch(err) {
    console.warn(err);
    return;
  }

}

<|endoftext|>