<commit_before>define(
  'ephox.darwin.keyboard.VerticalMovement',

  [
    'ephox.darwin.api.Responses',
    'ephox.darwin.keyboard.KeySelection',
    'ephox.darwin.keyboard.TableKeys',
    'ephox.fred.PlatformDetection',
    'ephox.fussy.api.SelectionRange',
    'ephox.fussy.api.Situ',
    'ephox.peanut.Fun',
    'ephox.perhaps.Option',
    'ephox.sugar.api.Compare',
    'ephox.sugar.api.PredicateExists',
    'ephox.sugar.api.SelectorFind',
    'ephox.sugar.api.Traverse'
  ],

  function (Responses, KeySelection, TableKeys, PlatformDetection, SelectionRange, Situ, Fun, Option, Compare, PredicateExists, SelectorFind, Traverse) {
    var detection = PlatformDetection.detect();

    var inSameTable = function (elem, table) {
      return PredicateExists.ancestor(elem, function (e) {
        return Traverse.parent(e).exists(function (p) {
          return Compare.eq(p, table);
        });
      });
    };

    // Note: initial is the finishing element, because that's where the cursor starts from
    // Anchor is the starting element, and is only used to work out if we are in the same table
    var simulate = function (bridge, isRoot, direction, initial, anchor) {
      return SelectorFind.closest(initial, 'td,th').bind(function (start) {
        return SelectorFind.closest(start, 'table').bind(function (table) {
          if (!inSameTable(anchor, table)) return Option.none();
          return TableKeys.handle(bridge, isRoot, direction).bind(function (range) {
            return SelectorFind.closest(range.finish(), 'td,th').map(function (finish) {
              return {
                start: Fun.constant(start),
                finish: Fun.constant(finish),
                range: Fun.constant(range)
              };
            });
          });
        });
      });
    };

    var navigate = function (bridge, isRoot, direction, initial, anchor) {
      // Do not override the up/down keys on Firefox or IE.
      if (detection.browser.isIE()) return Option.none();
      return simulate(bridge, isRoot, direction, initial, anchor).map(function (info) {
        var range = info.range();
        return Responses.response(
          Option.some(SelectionRange.write(
            Situ.on(range.start(), range.soffset()),
            Situ.on(range.finish(), range.foffset())
          )),
          true
        );
      });
    };

    var select = function (bridge, container, isRoot, direction, initial, anchor) {
      return simulate(bridge, isRoot, direction, initial, anchor).bind(function (info) {
        return KeySelection.detect(container, isRoot, info.start(), info.finish());
      });
    };

    return {<commit_msg>TBIO-4653: update comment<commit_after>define(
  'ephox.darwin.keyboard.VerticalMovement',

  [
    'ephox.darwin.api.Responses',
    'ephox.darwin.keyboard.KeySelection',
    'ephox.darwin.keyboard.TableKeys',
    'ephox.fred.PlatformDetection',
    'ephox.fussy.api.SelectionRange',
    'ephox.fussy.api.Situ',
    'ephox.peanut.Fun',
    'ephox.perhaps.Option',
    'ephox.sugar.api.Compare',
    'ephox.sugar.api.PredicateExists',
    'ephox.sugar.api.SelectorFind',
    'ephox.sugar.api.Traverse'
  ],

  function (Responses, KeySelection, TableKeys, PlatformDetection, SelectionRange, Situ, Fun, Option, Compare, PredicateExists, SelectorFind, Traverse) {
    var detection = PlatformDetection.detect();

    var inSameTable = function (elem, table) {
      return PredicateExists.ancestor(elem, function (e) {
        return Traverse.parent(e).exists(function (p) {
          return Compare.eq(p, table);
        });
      });
    };

    // Note: initial is the finishing element, because that's where the cursor starts from
    // Anchor is the starting element, and is only used to work out if we are in the same table
    var simulate = function (bridge, isRoot, direction, initial, anchor) {
      return SelectorFind.closest(initial, 'td,th').bind(function (start) {
        return SelectorFind.closest(start, 'table').bind(function (table) {
          if (!inSameTable(anchor, table)) return Option.none();
          return TableKeys.handle(bridge, isRoot, direction).bind(function (range) {
            return SelectorFind.closest(range.finish(), 'td,th').map(function (finish) {
              return {
                start: Fun.constant(start),
                finish: Fun.constant(finish),
                range: Fun.constant(range)
              };
            });
          });
        });
      });
    };

    var navigate = function (bridge, isRoot, direction, initial, anchor) {
      // Do not override the up/down keys on IE.
      if (detection.browser.isIE()) return Option.none();
      return simulate(bridge, isRoot, direction, initial, anchor).map(function (info) {
        var range = info.range();
        return Responses.response(
          Option.some(SelectionRange.write(
            Situ.on(range.start(), range.soffset()),
            Situ.on(range.finish(), range.foffset())
          )),
          true
        );
      });
    };

    var select = function (bridge, container, isRoot, direction, initial, anchor) {
      return simulate(bridge, isRoot, direction, initial, anchor).bind(function (info) {
        return KeySelection.detect(container, isRoot, info.start(), info.finish());
      });
    };

    return {
{'fraction_non_alphanumeric': 0.13225624647755024, 'fraction_numerical': 0.0007514559458951719, 'mean_word_length': 2.6666666666666665, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '6267304', 'n_tokens_mistral': 1580, 'n_tokens_neox': 1563, 'n_words': 352}