module.exports = {
  compact: function (arr) {
    var compactedArr = [];

    for (var i = 0; i < arr.length; i++) {
      arr[i] && compactedArr.push(arr[i]);
    }

    return compactedArr;
  },
  shallowClone: function (obj) {
    var clone = {};

    for (var key in obj) {
      clone[key] = obj[key];
    }

    return clone;
  },
  extend: function (dest, source) {
    for (var key in source) {
      dest[key] = source[key];
    }

    return dest;
  },
  uniq: function (arr) {
    var n = {},
      r = [],
      i;

    for (i = 0; i < arr.length; i++) {
      if (!n[arr[i]]) {
        n[arr[i]] = true;
        r.push(arr[i]);
      }
    }

    return r;
  },
  objectEach: function (obj, iterator) {
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) {
        iterator(obj[key], key);
      }
    }
  },
  isString: function (value) {
    return typeof value === 'string';
  },
  encode64: function (str) {
    var encodedUtf8Str = unescape(encodeURIComponent(str)),
      b64Str = btoa(encodedUtf8Str),
      urlSafeB64Str = b64Str.replace(/\+/g, '-');

    urlSafeB64Str = urlSafeB64Str
      .replace(/\//g, '_')
      .replace(/\//g, '_')
      .replace(/\=+$/, '');

    return urlSafeB64Str;
  },
  decode64: function (urlSafeB64Str) {
    var b64Str = urlSafeB64Str.replace(/-/g, '+').replace(/_/g, '/'),
      encodedUtf8Str = atob(b64Str),
      str = decodeURIComponent(escape(encodedUtf8Str));

    return str;
  },
  domReady: function (cb) {
    if (document.readyState === 'complete') {
      setTimeout(cb, 0);
    } else if (document.addEventListener) {
      document.addEventListener('DOMContentLoaded', cb, false);
    } else {
      document.attachEvent('onreadystatechange', function () {
        if (document.readyState === 'complete') {
          cb();
        }
      });
    }
  },
  getMetaTagValue: function (propertyName) {
    var metaTag = document.querySelector(
        'meta[property="ix:' + propertyName + '"]'
      ),
      metaTagContent;

    if (!metaTag) {
      return;
    }

    metaTagContent = metaTag.getAttribute('content');

    if (metaTagContent === 'true') {
      return true;
    } else if (metaTagContent === 'false') {
      return false;
    } else if (metaTagContent === '' || metaTagContent === 'null') {
      return null;
    } else {
      return metaTagContent;
    }
  },
  debounce: function (func, waitMs) {
    // based off: http://modernjavascript.blogspot.com/2013/08/building-better-debounce.html
    // we need to save these in the closure
    var timeout, args, context, timestamp;

    return function () {
      // save details of latest call
      context = this;
      args = [].slice.call(arguments, 0);
      timestamp = new Date();

      // this is where the magic happens
      var later = function () {
        // how long ago was the last call
        var timeSinceLastCallMs = new Date() - timestamp;

        // if the latest call was less that the wait period ago
        // then we reset the timeout to wait for the difference
        if (timeSinceLastCallMs < waitMs) {
          timeout = setTimeout(later, waitMs - timeSinceLastCallMs);

          // or if not we can null out the timer and run the latest
        } else {
          timeout = null;
          func.apply(context, args);
        }
      };

      // we only need to set the timer now if one isn't already running
      if (!timeout) {
        timeout = setTimeout(later, waitMs);
      }
    };
  },
  rICShim: function (_window) {
    // from: https://developers.google.com/web/updates/2015/08/using-requestidlecallback#checking_for_requestidlecallback
    return (
      _window.requestIdleCallback ||
      function (cb) {
        var start = Date.now();
        return setTimeout(function () {
          cb({
            didTimeout: false,
            timeRemaining: function () {
              return Math.max(0, 50 - (Date.now() - start));
            },
          });
        }, 1);
      }
    );
  },
};

@@ -1,8 +1,55 @@
+const _debounce = require('lodash.debounce');%0A%0A
 module.e
@@ -2420,1113 +2420,17 @@
 ce: 
-function (func, waitMs) %7B%0A    // based off: http://modernjavascript.blogspot.com/2013/08/building-better-debounce.html%0A    // we need to save these in the closure%0A    var timeout, args, context, timestamp;%0A%0A    return function () %7B%0A      // save details of latest call%0A      context = this;%0A      args = %5B%5D.slice.call(arguments, 0);%0A      timestamp = new Date();%0A%0A      // this is where the magic happens%0A      var later = function () %7B%0A        // how long ago was the last call%0A        var timeSinceLastCallMs = new Date() - timestamp;%0A%0A        // if the latest call was less that the wait period ago%0A        // then we reset the timeout to wait for the difference%0A        if (timeSinceLastCallMs %3C waitMs) %7B%0A          timeout = setTimeout(later, waitMs - timeSinceLastCallMs);%0A%0A          // or if not we can null out the timer and run the latest%0A        %7D else %7B%0A          timeout = null;%0A          func.apply(context, args);%0A        %7D%0A      %7D;%0A%0A      // we only need to set the timer now if one isn't already running%0A      if (!timeout) %7B%0A        timeout = setTimeout(later, waitMs);%0A      %7D%0A    %7D;%0A  %7D
+_debounce
 ,%0A  

use lodash debounce package