<commit_before>const {noTarget, isOfMetaType, isInactiveFeature, isShiftDown} = require('../lib/common_selectors');
const createSupplementaryPoints = require('../lib/create_supplementary_points');
const constrainFeatureMovement = require('../lib/constrain_feature_movement');
const doubleClickZoom = require('../lib/double_click_zoom');
const Constants = require('../constants');
const CommonSelectors = require('../lib/common_selectors');
const moveFeatures = require('../lib/move_features');

const isVertex = isOfMetaType(Constants.meta.VERTEX);
const isMidpoint = isOfMetaType(Constants.meta.MIDPOINT);

module.exports = function(ctx, opts) {
  let featureId = opts.featureId;
  let feature = ctx.store.get(featureId);
  let dragFeature = opts.dragFeature;

  if (!feature) {
    throw new Error('You must provide a featureId to enter direct_select mode');
  }

  if (feature.type === Constants.geojsonTypes.POINT) {
    throw new TypeError('direct_select mode doesn\'t handle point features');
  }

  let dragMoveLocation = opts.startPos || null;
  let dragMoving = false;
  let canDragMove = false;

  let selectedCoordPaths = opts.coordPath ? [opts.coordPath] : [];

  let dragMode = null;

  const onVertex = function(e) {
    startDragging(e);
    dragMode = 'vertex';
    let about = e.featureTarget.properties;
    let selectedIndex = selectedCoordPaths.indexOf(about.coord_path);
    if (!isShiftDown(e) && selectedIndex === -1) {
      selectedCoordPaths = [about.coord_path];
    }
    else if (isShiftDown(e) && selectedIndex === -1) {
      selectedCoordPaths.push(about.coord_path);
    }
    feature.changed();
  };

  const onMidpoint = function(e) {
    startDragging(e);
    dragMode = 'midpoint';
    let about = e.featureTarget.properties;
    feature.addCoordinate(about.coord_path, about.lng, about.lat);
    ctx.map.fire(Constants.events.UPDATE, {
      action: Constants.updateActions.CHANGE_COORDINATES,
      features: ctx.store.getSelected().map(f => f.toGeoJSON())
    });
    selectedCoordPaths = [about.coord_path];
  };

  const startDragging = function(e) {
    ctx.map.dragPan.disable();
    canDragMove = true;
    dragMoveLocation = e.lngLat;
  };

  const stopDragging = function() {
    ctx.map.dragPan.enable();
    dragMoving = false;
    canDragMove = false;
    dragMoveLocation = null;
  };

  return {
    start: function() {
      ctx.store.setSelected(featureId);
      doubleClickZoom.disable(ctx);

      // On mousemove that is not a drag, stop vertex movement.
      this.on('mousemove', CommonSelectors.true, stopDragging);

      this.on('mousedown', isVertex, onVertex);
      this.on('mousedown', isMidpoint, onMidpoint);

      if (dragFeature) {

        this.on('mousedown', CommonSelectors.isActiveFeature, function (e) {
          dragMode = 'feature';

          ctx.map.dragPan.disable();
          this.render(e.featureTarget.properties.id);

          // Set up the state for drag moving
          dragMoving = false;
          canDragMove = true;
          dragMoveLocation = e.lngLat;
        });
      }

      this.on('drag', () => canDragMove, function(e) {

        if (dragFeature && dragMode === 'feature') {

          dragMoving = true;
          e.originalEvent.stopPropagation();

          const delta = {
            lng: e.lngLat.lng - dragMoveLocation.lng,
            lat: e.lngLat.lat - dragMoveLocation.lat
          };

          moveFeatures(ctx.store.getSelected(), delta);

          dragMoveLocation = e.lngLat;

        } else {

          dragMoving = true;
          e.originalEvent.stopPropagation();

          let selectedCoords = selectedCoordPaths.map(coord_path => feature.getCoordinate(coord_path));
          let selectedCoordPoints = selectedCoords.map(coords => ({
            type      : Constants.geojsonTypes.FEATURE,
            properties: {},<commit_msg>Code review changes<commit_after>const {noTarget, isOfMetaType, isInactiveFeature, isShiftDown} = require('../lib/common_selectors');
const createSupplementaryPoints = require('../lib/create_supplementary_points');
const constrainFeatureMovement = require('../lib/constrain_feature_movement');
const doubleClickZoom = require('../lib/double_click_zoom');
const Constants = require('../constants');
const CommonSelectors = require('../lib/common_selectors');
const moveFeatures = require('../lib/move_features');

const isVertex = isOfMetaType(Constants.meta.VERTEX);
const isMidpoint = isOfMetaType(Constants.meta.MIDPOINT);

module.exports = function(ctx, opts) {
  let featureId = opts.featureId;
  let feature = ctx.store.get(featureId);
  let dragFeature = opts.dragFeature;

  if (!feature) {
    throw new Error('You must provide a featureId to enter direct_select mode');
  }

  if (feature.type === Constants.geojsonTypes.POINT) {
    throw new TypeError('direct_select mode doesn\'t handle point features');
  }

  let dragMoveLocation = opts.startPos || null;
  let dragMoving = false;
  let canDragMove = false;

  let selectedCoordPaths = opts.coordPath ? [opts.coordPath] : [];

  let dragMode = null;

  const onVertex = function(e) {
    startDragging(e);
    dragMode = 'vertex';
    let about = e.featureTarget.properties;
    let selectedIndex = selectedCoordPaths.indexOf(about.coord_path);
    if (!isShiftDown(e) && selectedIndex === -1) {
      selectedCoordPaths = [about.coord_path];
    }
    else if (isShiftDown(e) && selectedIndex === -1) {
      selectedCoordPaths.push(about.coord_path);
    }
    feature.changed();
  };

  const onMidpoint = function(e) {
    startDragging(e);
    dragMode = 'midpoint';
    let about = e.featureTarget.properties;
    feature.addCoordinate(about.coord_path, about.lng, about.lat);
    ctx.map.fire(Constants.events.UPDATE, {
      action: Constants.updateActions.CHANGE_COORDINATES,
      features: ctx.store.getSelected().map(f => f.toGeoJSON())
    });
    selectedCoordPaths = [about.coord_path];
  };

  const startDragging = function(e) {
    ctx.map.dragPan.disable();
    canDragMove = true;
    dragMoveLocation = e.lngLat;
  };

  const stopDragging = function() {
    ctx.map.dragPan.enable();
    dragMoving = false;
    canDragMove = false;
    dragMoveLocation = null;
  };

  return {
    start: function() {
      ctx.store.setSelected(featureId);
      doubleClickZoom.disable(ctx);

      // On mousemove that is not a drag, stop vertex movement.
      this.on('mousemove', CommonSelectors.true, stopDragging);

      this.on('mousedown', isVertex, onVertex);
      this.on('mousedown', isMidpoint, onMidpoint);

      if (dragFeature) {

        this.on('mousedown', CommonSelectors.isActiveFeature, function (e) {
          dragMode = 'feature';

          startDragging(e);
          dragMoving = false;

          this.render(e.featureTarget.properties.id);
        });
      }

      this.on('drag', () => canDragMove, function(e) {

        if (dragFeature && dragMode === 'feature') {

          dragMoving = true;
          e.originalEvent.stopPropagation();

          const delta = {
            lng: e.lngLat.lng - dragMoveLocation.lng,
            lat: e.lngLat.lat - dragMoveLocation.lat
          };

          moveFeatures(ctx.store.getSelected(), delta);

          dragMoveLocation = e.lngLat;

        } else {

          dragMoving = true;
          e.originalEvent.stopPropagation();

          let selectedCoords = selectedCoordPaths.map(coord_path => feature.getCoordinate(coord_path));
          let selectedCoordPoints = selectedCoords.map(coords => ({
            type      : Constants.geojsonTypes.FEATURE,
            properties: {},
{'fraction_non_alphanumeric': 0.12647909545095976, 'fraction_numerical': 0.0005259006047856955, 'mean_word_length': 3.096392030156166, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6407877', 'n_tokens_mistral': 2320, 'n_tokens_neox': 2241, 'n_words': 449}