<commit_before>// Sortable decorator
// Allows a list to be reordered with drag-and-drop.
module.exports = function sortable(listEl, keypath, index) {
    var el;
    var startY;
    var startIndex, currentIndex;
    var origNextNode;
    var ractive = this;

    // find the element ancestor corresponding to an item in our list
    function findEl(child) {
        for (var el = child;
            el && el.parentNode != listEl;
            el = el.parentNode);
        return el;
    }

    function onDrag(e) {
        var height = el.clientHeight;

        // swap item down the list
        while (e.clientY - startY > height/2 && el.nextElementSibling) {
            startY += height;
            currentIndex++;
            var nextEl = el.nextElementSibling;
            if (nextEl.nextElementSibling) {
                listEl.insertBefore(el, nextEl.nextElementSibling);
            } else {
                listEl.appendChild(el);
            }
        }

        // swap item up the list
        while (e.clientY - startY < -height/2 &&
                el.previousElementSibling) {
            currentIndex--;
            startY -= height;
            listEl.insertBefore(el, el.previousElementSibling);
        }

        el.style.top = (e.clientY - startY) + 'px';
    }

    function onDragEnd(e) {
        document.removeEventListener('mousemove', onDrag, false);
        document.removeEventListener('mouseup', onDragEnd, false);
        onDrag(e);

        var itemEl = el;
        el.classList.remove('ui-sortable-helper');
        el.style.position = '';
        el.style.top = '';
        el.style.zIndex = '';
        listEl.style.overflow = '';
        el = null;

        if (currentIndex == startIndex) {
            // node did not move
            return;
        }

        // put element back in place
        if (origNextNode) {
            listEl.insertBefore(itemEl, origNextNode);
        } else {
            listEl.appendChild(itemEl);
        }

        // update model
        var arrayOrig = ractive.get(keypath);
        var array = arrayOrig.slice();
        var item = array[startIndex];
        if (!item) {
            console.error('Unable to find item', array, startIndex);
            return;
        }
        item.playlistPosition = currentIndex;
        // remove item from old position
        array.splice(startIndex, 1);
        // add item to array at new position
        array.splice(currentIndex, 0, item);

        array._dragging = true;
        //ractive.merge(keypath, array);
        /*
        arrayOrig.sort(function(a, b) {
            return array.indexOf(a) - array.indexOf(b);
        });
        */
        ractive.set(keypath, array);

        array._dragging = false;
    }

    function onMouseDown(e) {
        e.preventDefault();

        if (el) {
            // finish previous drag
            onDragEnd(e);
            return;
        }
<commit_msg>Ignore right click in playlist organizer<commit_after>// Sortable decorator
// Allows a list to be reordered with drag-and-drop.
module.exports = function sortable(listEl, keypath, index) {
    var el;
    var startY;
    var startIndex, currentIndex;
    var origNextNode;
    var ractive = this;

    // find the element ancestor corresponding to an item in our list
    function findEl(child) {
        for (var el = child;
            el && el.parentNode != listEl;
            el = el.parentNode);
        return el;
    }

    function onDrag(e) {
        var height = el.clientHeight;

        // swap item down the list
        while (e.clientY - startY > height/2 && el.nextElementSibling) {
            startY += height;
            currentIndex++;
            var nextEl = el.nextElementSibling;
            if (nextEl.nextElementSibling) {
                listEl.insertBefore(el, nextEl.nextElementSibling);
            } else {
                listEl.appendChild(el);
            }
        }

        // swap item up the list
        while (e.clientY - startY < -height/2 &&
                el.previousElementSibling) {
            currentIndex--;
            startY -= height;
            listEl.insertBefore(el, el.previousElementSibling);
        }

        el.style.top = (e.clientY - startY) + 'px';
    }

    function onDragEnd(e) {
        document.removeEventListener('mousemove', onDrag, false);
        document.removeEventListener('mouseup', onDragEnd, false);
        onDrag(e);

        var itemEl = el;
        el.classList.remove('ui-sortable-helper');
        el.style.position = '';
        el.style.top = '';
        el.style.zIndex = '';
        listEl.style.overflow = '';
        el = null;

        if (currentIndex == startIndex) {
            // node did not move
            return;
        }

        // put element back in place
        if (origNextNode) {
            listEl.insertBefore(itemEl, origNextNode);
        } else {
            listEl.appendChild(itemEl);
        }

        // update model
        var arrayOrig = ractive.get(keypath);
        var array = arrayOrig.slice();
        var item = array[startIndex];
        if (!item) {
            console.error('Unable to find item', array, startIndex);
            return;
        }
        item.playlistPosition = currentIndex;
        // remove item from old position
        array.splice(startIndex, 1);
        // add item to array at new position
        array.splice(currentIndex, 0, item);

        array._dragging = true;
        //ractive.merge(keypath, array);
        /*
        arrayOrig.sort(function(a, b) {
            return array.indexOf(a) - array.indexOf(b);
        });
        */
        ractive.set(keypath, array);

        array._dragging = false;
    }

    function onMouseDown(e) {
        if (e.button == 2) {
            // leave right click alone
            return;
        }

        e.preventDefault();

        if (el) {
            // finish previous drag
            onDragEnd(e);
            return;
        }

{'fraction_non_alphanumeric': 0.10772833723653395, 'fraction_numerical': 0.0015055202408832385, 'mean_word_length': 1.6154855643044619, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '69102', 'n_tokens_mistral': 1697, 'n_tokens_neox': 1661, 'n_words': 409}