<commit_before>lichess = window.lichess || {};

lichess.engineName = 'Stockfish 10+';

lichess.raf = window.requestAnimationFrame.bind(window);
lichess.requestIdleCallback = (window.requestIdleCallback || window.setTimeout).bind(window);
lichess.dispatchEvent = function(el, eventName) {
  el.dispatchEvent(new Event(eventName));
};

function buildStorage(storageKey) {
  try {
    // just accessing localStorage can throw an exception...
    var storage = window[storageKey];
  } catch (e) {}
  var withStorage = storage ? function(f) {
    // this can throw exceptions as well.
    try { return f(storage); }
    catch (e) {}
  } : function() {};
  var storageObj = {
    get: function(k) {
      return withStorage(function(s) {
        return s.getItem(k);
      });
    },
    set: function(k, v) {
      withStorage(function(s) {
        try {
          s.setItem(k, v);
        } catch (e) {
          // removing first may help http://stackoverflow.com/questions/2603682/is-anyone-else-receiving-a-quota-exceeded-err-on-their-ipad-when-accessing-local
          s.removeItem(k);
          s.setItem(k, v);
        }
      });
    },
    remove: function(k) {
      withStorage(function(s) {
        s.removeItem(k);
      });
    },
    make: function(k) {
      return {
        get: function() {
          return storageObj.get(k);
        },
        set: function(v) {
          return storageObj.set(k, v);
        },
        remove: function() {
          return storageObj.remove(k);
        },
        listen: function(f) {
          window.addEventListener('storage', function(e) {
            if (e.key === k &&
              e.storageArea === storage &&
              e.newValue !== null) f(e);
          });
        }
      };
    }
  };
  return storageObj;
};

lichess.storage = buildStorage('localStorage');

lichess.once = function(key, mod) {
  if (mod === 'always') return true;
  if (!lichess.storage.get(key)) {
    lichess.storage.set(key, 1);
    return true;
  }
  return false;
};
lichess.debounce = function(func, wait, immediate) {
  var timeout;
  var lastBounce = 0;
  return function() {
    var context = this,
      args = arguments,
      elapsed = Date.now() - lastBounce;
    lastBounce = Date.now();
    var later = function() {
      timeout = null;
      func.apply(context, args);
    };
    clearTimeout(timeout);
    if (immediate && elapsed > wait) func.apply(context, args);
    else timeout = setTimeout(later, wait);
  };
};
lichess.powertip = (function() {

  function containedIn(el, container) {
    return container && container.contains(el);
  }
  function inCrosstable(el) {
    return containedIn(el, document.querySelector('.crosstable'));
  }

  var onPowertipPreRender = function(id, preload) {
    return function() {
      var url = ($(this).data('href') || $(this).attr('href')).replace(/\?.+$/, '');
      if (preload) preload(url);
      $.ajax({
        url: url + '/mini',
        success: function(html) {
          $('#' + id).html(html);
          lichess.pubsub.emit('content_loaded')();
        }
      });
    };
  };

  var uptA = function(url, icon) {
    return '<a class="btn-rack__btn" href="' + url + '" data-icon="' + icon + '"></a>';
  }
  var userPowertip = function(el, pos) {
    pos = pos || el.getAttribute('data-pt-pos') || (
      inCrosstable(el) ? 'n' : 's'
    );
    $(el).removeClass('ulpt').powerTip({
      intentPollInterval: 200,
      placement: pos,
      mouseOnToPopup: true,
      closeDelay: 200
    }).data('powertip', ' ').on({
      powerTipRender: onPowertipPreRender('powerTip', function(url) {
        var u = url.substr(3);
        $('#powerTip').html('<div class="upt__info"><div class="upt__info__top"><span class="user-link offline">' + $(el).html() + '</span></div></div><div class="upt__actions btn-rack">' +
          uptA('/@/' + u + '/tv', '1') +
          uptA('/inbox/new?user=' + u, 'c') +
          uptA('/?user=' + u + '#friend', 'U') +
          '<a class="btn-rack__btn relation-button" disabled></a></div>');
      })
    });
  };

  var gamePowertip = function(el) {
    $(el).removeClass('glpt').powerTip({
      intentPollInterval: 200,
      placement: inCrosstable(el) ? 'n' : 'w',
      smartPlacement: true,
      mouseOnToPopup: true,
      closeDelay: 200,
      popupId: 'miniGame'
    }).on({
      powerTipPreRender: onPowertipPreRender('miniGame')
    }).data('powertip', lichess.spinnerHtml);
  };
<commit_msg>enable smart placement on user powertips<commit_after>lichess = window.lichess || {};

lichess.engineName = 'Stockfish 10+';

lichess.raf = window.requestAnimationFrame.bind(window);
lichess.requestIdleCallback = (window.requestIdleCallback || window.setTimeout).bind(window);
lichess.dispatchEvent = function(el, eventName) {
  el.dispatchEvent(new Event(eventName));
};

function buildStorage(storageKey) {
  try {
    // just accessing localStorage can throw an exception...
    var storage = window[storageKey];
  } catch (e) {}
  var withStorage = storage ? function(f) {
    // this can throw exceptions as well.
    try { return f(storage); }
    catch (e) {}
  } : function() {};
  var storageObj = {
    get: function(k) {
      return withStorage(function(s) {
        return s.getItem(k);
      });
    },
    set: function(k, v) {
      withStorage(function(s) {
        try {
          s.setItem(k, v);
        } catch (e) {
          // removing first may help http://stackoverflow.com/questions/2603682/is-anyone-else-receiving-a-quota-exceeded-err-on-their-ipad-when-accessing-local
          s.removeItem(k);
          s.setItem(k, v);
        }
      });
    },
    remove: function(k) {
      withStorage(function(s) {
        s.removeItem(k);
      });
    },
    make: function(k) {
      return {
        get: function() {
          return storageObj.get(k);
        },
        set: function(v) {
          return storageObj.set(k, v);
        },
        remove: function() {
          return storageObj.remove(k);
        },
        listen: function(f) {
          window.addEventListener('storage', function(e) {
            if (e.key === k &&
              e.storageArea === storage &&
              e.newValue !== null) f(e);
          });
        }
      };
    }
  };
  return storageObj;
};

lichess.storage = buildStorage('localStorage');

lichess.once = function(key, mod) {
  if (mod === 'always') return true;
  if (!lichess.storage.get(key)) {
    lichess.storage.set(key, 1);
    return true;
  }
  return false;
};
lichess.debounce = function(func, wait, immediate) {
  var timeout;
  var lastBounce = 0;
  return function() {
    var context = this,
      args = arguments,
      elapsed = Date.now() - lastBounce;
    lastBounce = Date.now();
    var later = function() {
      timeout = null;
      func.apply(context, args);
    };
    clearTimeout(timeout);
    if (immediate && elapsed > wait) func.apply(context, args);
    else timeout = setTimeout(later, wait);
  };
};
lichess.powertip = (function() {

  function containedIn(el, container) {
    return container && container.contains(el);
  }
  function inCrosstable(el) {
    return containedIn(el, document.querySelector('.crosstable'));
  }

  var onPowertipPreRender = function(id, preload) {
    return function() {
      var url = ($(this).data('href') || $(this).attr('href')).replace(/\?.+$/, '');
      if (preload) preload(url);
      $.ajax({
        url: url + '/mini',
        success: function(html) {
          $('#' + id).html(html);
          lichess.pubsub.emit('content_loaded')();
        }
      });
    };
  };

  var uptA = function(url, icon) {
    return '<a class="btn-rack__btn" href="' + url + '" data-icon="' + icon + '"></a>';
  }
  var userPowertip = function(el, pos) {
    pos = pos || el.getAttribute('data-pt-pos') || (
      inCrosstable(el) ? 'n' : 's'
    );
    $(el).removeClass('ulpt').powerTip({
      intentPollInterval: 200,
      placement: pos,
      smartPlacement: true,
      mouseOnToPopup: true,
      closeDelay: 200
    }).data('powertip', ' ').on({
      powerTipRender: onPowertipPreRender('powerTip', function(url) {
        var u = url.substr(3);
        $('#powerTip').html('<div class="upt__info"><div class="upt__info__top"><span class="user-link offline">' + $(el).html() + '</span></div></div><div class="upt__actions btn-rack">' +
          uptA('/@/' + u + '/tv', '1') +
          uptA('/inbox/new?user=' + u, 'c') +
          uptA('/?user=' + u + '#friend', 'U') +
          '<a class="btn-rack__btn relation-button" disabled></a></div>');
      })
    });
  };

  var gamePowertip = function(el) {
    $(el).removeClass('glpt').powerTip({
      intentPollInterval: 200,
      placement: inCrosstable(el) ? 'n' : 'w',
      smartPlacement: true,
      mouseOnToPopup: true,
      closeDelay: 200,
      popupId: 'miniGame'
    }).on({
      powerTipPreRender: onPowertipPreRender('miniGame')
    }).data('powertip', lichess.spinnerHtml);
  };

{'fraction_non_alphanumeric': 0.17260243385061963, 'fraction_numerical': 0.005582226191805292, 'mean_word_length': 2.5212264150943398, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 29, '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': '1187672', 'n_tokens_mistral': 2982, 'n_tokens_neox': 2891, 'n_words': 571}