|  | @@ -0,0 +1,447 @@
 | 
	
		
			
				|  |  | +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.DragDrop = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
 | 
	
		
			
				|  |  | +// shim for using process in browser
 | 
	
		
			
				|  |  | +var process = module.exports = {};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// cached from whatever global is present so that test runners that stub it
 | 
	
		
			
				|  |  | +// don't break things.  But we need to wrap it in a try catch in case it is
 | 
	
		
			
				|  |  | +// wrapped in strict mode code which doesn't define any globals.  It's inside a
 | 
	
		
			
				|  |  | +// function because try/catches deoptimize in certain engines.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +var cachedSetTimeout;
 | 
	
		
			
				|  |  | +var cachedClearTimeout;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +function defaultSetTimout() {
 | 
	
		
			
				|  |  | +    throw new Error('setTimeout has not been defined');
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +function defaultClearTimeout () {
 | 
	
		
			
				|  |  | +    throw new Error('clearTimeout has not been defined');
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +(function () {
 | 
	
		
			
				|  |  | +    try {
 | 
	
		
			
				|  |  | +        if (typeof setTimeout === 'function') {
 | 
	
		
			
				|  |  | +            cachedSetTimeout = setTimeout;
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            cachedSetTimeout = defaultSetTimout;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    } catch (e) {
 | 
	
		
			
				|  |  | +        cachedSetTimeout = defaultSetTimout;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    try {
 | 
	
		
			
				|  |  | +        if (typeof clearTimeout === 'function') {
 | 
	
		
			
				|  |  | +            cachedClearTimeout = clearTimeout;
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            cachedClearTimeout = defaultClearTimeout;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    } catch (e) {
 | 
	
		
			
				|  |  | +        cachedClearTimeout = defaultClearTimeout;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +} ())
 | 
	
		
			
				|  |  | +function runTimeout(fun) {
 | 
	
		
			
				|  |  | +    if (cachedSetTimeout === setTimeout) {
 | 
	
		
			
				|  |  | +        //normal enviroments in sane situations
 | 
	
		
			
				|  |  | +        return setTimeout(fun, 0);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    // if setTimeout wasn't available but was latter defined
 | 
	
		
			
				|  |  | +    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
 | 
	
		
			
				|  |  | +        cachedSetTimeout = setTimeout;
 | 
	
		
			
				|  |  | +        return setTimeout(fun, 0);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    try {
 | 
	
		
			
				|  |  | +        // when when somebody has screwed with setTimeout but no I.E. maddness
 | 
	
		
			
				|  |  | +        return cachedSetTimeout(fun, 0);
 | 
	
		
			
				|  |  | +    } catch(e){
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
 | 
	
		
			
				|  |  | +            return cachedSetTimeout.call(null, fun, 0);
 | 
	
		
			
				|  |  | +        } catch(e){
 | 
	
		
			
				|  |  | +            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
 | 
	
		
			
				|  |  | +            return cachedSetTimeout.call(this, fun, 0);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +function runClearTimeout(marker) {
 | 
	
		
			
				|  |  | +    if (cachedClearTimeout === clearTimeout) {
 | 
	
		
			
				|  |  | +        //normal enviroments in sane situations
 | 
	
		
			
				|  |  | +        return clearTimeout(marker);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    // if clearTimeout wasn't available but was latter defined
 | 
	
		
			
				|  |  | +    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
 | 
	
		
			
				|  |  | +        cachedClearTimeout = clearTimeout;
 | 
	
		
			
				|  |  | +        return clearTimeout(marker);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    try {
 | 
	
		
			
				|  |  | +        // when when somebody has screwed with setTimeout but no I.E. maddness
 | 
	
		
			
				|  |  | +        return cachedClearTimeout(marker);
 | 
	
		
			
				|  |  | +    } catch (e){
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
 | 
	
		
			
				|  |  | +            return cachedClearTimeout.call(null, marker);
 | 
	
		
			
				|  |  | +        } catch (e){
 | 
	
		
			
				|  |  | +            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
 | 
	
		
			
				|  |  | +            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
 | 
	
		
			
				|  |  | +            return cachedClearTimeout.call(this, marker);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +var queue = [];
 | 
	
		
			
				|  |  | +var draining = false;
 | 
	
		
			
				|  |  | +var currentQueue;
 | 
	
		
			
				|  |  | +var queueIndex = -1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +function cleanUpNextTick() {
 | 
	
		
			
				|  |  | +    if (!draining || !currentQueue) {
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    draining = false;
 | 
	
		
			
				|  |  | +    if (currentQueue.length) {
 | 
	
		
			
				|  |  | +        queue = currentQueue.concat(queue);
 | 
	
		
			
				|  |  | +    } else {
 | 
	
		
			
				|  |  | +        queueIndex = -1;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if (queue.length) {
 | 
	
		
			
				|  |  | +        drainQueue();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +function drainQueue() {
 | 
	
		
			
				|  |  | +    if (draining) {
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    var timeout = runTimeout(cleanUpNextTick);
 | 
	
		
			
				|  |  | +    draining = true;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    var len = queue.length;
 | 
	
		
			
				|  |  | +    while(len) {
 | 
	
		
			
				|  |  | +        currentQueue = queue;
 | 
	
		
			
				|  |  | +        queue = [];
 | 
	
		
			
				|  |  | +        while (++queueIndex < len) {
 | 
	
		
			
				|  |  | +            if (currentQueue) {
 | 
	
		
			
				|  |  | +                currentQueue[queueIndex].run();
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        queueIndex = -1;
 | 
	
		
			
				|  |  | +        len = queue.length;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    currentQueue = null;
 | 
	
		
			
				|  |  | +    draining = false;
 | 
	
		
			
				|  |  | +    runClearTimeout(timeout);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +process.nextTick = function (fun) {
 | 
	
		
			
				|  |  | +    var args = new Array(arguments.length - 1);
 | 
	
		
			
				|  |  | +    if (arguments.length > 1) {
 | 
	
		
			
				|  |  | +        for (var i = 1; i < arguments.length; i++) {
 | 
	
		
			
				|  |  | +            args[i - 1] = arguments[i];
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    queue.push(new Item(fun, args));
 | 
	
		
			
				|  |  | +    if (queue.length === 1 && !draining) {
 | 
	
		
			
				|  |  | +        runTimeout(drainQueue);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// v8 likes predictible objects
 | 
	
		
			
				|  |  | +function Item(fun, array) {
 | 
	
		
			
				|  |  | +    this.fun = fun;
 | 
	
		
			
				|  |  | +    this.array = array;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +Item.prototype.run = function () {
 | 
	
		
			
				|  |  | +    this.fun.apply(null, this.array);
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +process.title = 'browser';
 | 
	
		
			
				|  |  | +process.browser = true;
 | 
	
		
			
				|  |  | +process.env = {};
 | 
	
		
			
				|  |  | +process.argv = [];
 | 
	
		
			
				|  |  | +process.version = ''; // empty string to avoid regexp issues
 | 
	
		
			
				|  |  | +process.versions = {};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +function noop() {}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +process.on = noop;
 | 
	
		
			
				|  |  | +process.addListener = noop;
 | 
	
		
			
				|  |  | +process.once = noop;
 | 
	
		
			
				|  |  | +process.off = noop;
 | 
	
		
			
				|  |  | +process.removeListener = noop;
 | 
	
		
			
				|  |  | +process.removeAllListeners = noop;
 | 
	
		
			
				|  |  | +process.emit = noop;
 | 
	
		
			
				|  |  | +process.prependListener = noop;
 | 
	
		
			
				|  |  | +process.prependOnceListener = noop;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +process.listeners = function (name) { return [] }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +process.binding = function (name) {
 | 
	
		
			
				|  |  | +    throw new Error('process.binding is not supported');
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +process.cwd = function () { return '/' };
 | 
	
		
			
				|  |  | +process.chdir = function (dir) {
 | 
	
		
			
				|  |  | +    throw new Error('process.chdir is not supported');
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +process.umask = function() { return 0; };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +},{}],2:[function(require,module,exports){
 | 
	
		
			
				|  |  | +(function (process){
 | 
	
		
			
				|  |  | +module.exports = runParallel
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +function runParallel (tasks, cb) {
 | 
	
		
			
				|  |  | +  var results, pending, keys
 | 
	
		
			
				|  |  | +  var isSync = true
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (Array.isArray(tasks)) {
 | 
	
		
			
				|  |  | +    results = []
 | 
	
		
			
				|  |  | +    pending = tasks.length
 | 
	
		
			
				|  |  | +  } else {
 | 
	
		
			
				|  |  | +    keys = Object.keys(tasks)
 | 
	
		
			
				|  |  | +    results = {}
 | 
	
		
			
				|  |  | +    pending = keys.length
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function done (err) {
 | 
	
		
			
				|  |  | +    function end () {
 | 
	
		
			
				|  |  | +      if (cb) cb(err, results)
 | 
	
		
			
				|  |  | +      cb = null
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if (isSync) process.nextTick(end)
 | 
	
		
			
				|  |  | +    else end()
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function each (i, err, result) {
 | 
	
		
			
				|  |  | +    results[i] = result
 | 
	
		
			
				|  |  | +    if (--pending === 0 || err) {
 | 
	
		
			
				|  |  | +      done(err)
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (!pending) {
 | 
	
		
			
				|  |  | +    // empty
 | 
	
		
			
				|  |  | +    done(null)
 | 
	
		
			
				|  |  | +  } else if (keys) {
 | 
	
		
			
				|  |  | +    // object
 | 
	
		
			
				|  |  | +    keys.forEach(function (key) {
 | 
	
		
			
				|  |  | +      tasks[key](function (err, result) { each(key, err, result) })
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +  } else {
 | 
	
		
			
				|  |  | +    // array
 | 
	
		
			
				|  |  | +    tasks.forEach(function (task, i) {
 | 
	
		
			
				|  |  | +      task(function (err, result) { each(i, err, result) })
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  isSync = false
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}).call(this,require('_process'))
 | 
	
		
			
				|  |  | +},{"_process":1}],"/":[function(require,module,exports){
 | 
	
		
			
				|  |  | +module.exports = dragDrop
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const parallel = require('run-parallel')
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +function dragDrop (elem, listeners) {
 | 
	
		
			
				|  |  | +  if (typeof elem === 'string') {
 | 
	
		
			
				|  |  | +    const selector = elem
 | 
	
		
			
				|  |  | +    elem = window.document.querySelector(elem)
 | 
	
		
			
				|  |  | +    if (!elem) {
 | 
	
		
			
				|  |  | +      throw new Error(`"${selector}" does not match any HTML elements`)
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (!elem) {
 | 
	
		
			
				|  |  | +    throw new Error(`"${elem}" is not a valid HTML element`)
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (typeof listeners === 'function') {
 | 
	
		
			
				|  |  | +    listeners = { onDrop: listeners }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  let timeout
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  elem.addEventListener('dragenter', onDragEnter, false)
 | 
	
		
			
				|  |  | +  elem.addEventListener('dragover', onDragOver, false)
 | 
	
		
			
				|  |  | +  elem.addEventListener('dragleave', onDragLeave, false)
 | 
	
		
			
				|  |  | +  elem.addEventListener('drop', onDrop, false)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // Function to remove drag-drop listeners
 | 
	
		
			
				|  |  | +  return function remove () {
 | 
	
		
			
				|  |  | +    removeDragClass()
 | 
	
		
			
				|  |  | +    elem.removeEventListener('dragenter', onDragEnter, false)
 | 
	
		
			
				|  |  | +    elem.removeEventListener('dragover', onDragOver, false)
 | 
	
		
			
				|  |  | +    elem.removeEventListener('dragleave', onDragLeave, false)
 | 
	
		
			
				|  |  | +    elem.removeEventListener('drop', onDrop, false)
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function onDragEnter (e) {
 | 
	
		
			
				|  |  | +    if (listeners.onDragEnter) {
 | 
	
		
			
				|  |  | +      listeners.onDragEnter(e)
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Prevent event
 | 
	
		
			
				|  |  | +    e.stopPropagation()
 | 
	
		
			
				|  |  | +    e.preventDefault()
 | 
	
		
			
				|  |  | +    return false
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function onDragOver (e) {
 | 
	
		
			
				|  |  | +    e.stopPropagation()
 | 
	
		
			
				|  |  | +    e.preventDefault()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    if (listeners.onDragOver) {
 | 
	
		
			
				|  |  | +      listeners.onDragOver(e)
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    if (e.dataTransfer.items) {
 | 
	
		
			
				|  |  | +      // Only add "drag" class when `items` contains items that are able to be
 | 
	
		
			
				|  |  | +      // handled by the registered listeners (files vs. text)
 | 
	
		
			
				|  |  | +      const items = Array.from(e.dataTransfer.items)
 | 
	
		
			
				|  |  | +      const fileItems = items.filter(item => { return item.kind === 'file' })
 | 
	
		
			
				|  |  | +      const textItems = items.filter(item => { return item.kind === 'string' })
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      if (fileItems.length === 0 && !listeners.onDropText) return
 | 
	
		
			
				|  |  | +      if (textItems.length === 0 && !listeners.onDrop) return
 | 
	
		
			
				|  |  | +      if (fileItems.length === 0 && textItems.length === 0) return
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    elem.classList.add('drag')
 | 
	
		
			
				|  |  | +    clearTimeout(timeout)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    e.dataTransfer.dropEffect = 'copy'
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return false
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function onDragLeave (e) {
 | 
	
		
			
				|  |  | +    e.stopPropagation()
 | 
	
		
			
				|  |  | +    e.preventDefault()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    if (listeners.onDragLeave) {
 | 
	
		
			
				|  |  | +      listeners.onDragLeave(e)
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    clearTimeout(timeout)
 | 
	
		
			
				|  |  | +    timeout = setTimeout(removeDragClass, 50)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return false
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function onDrop (e) {
 | 
	
		
			
				|  |  | +    e.stopPropagation()
 | 
	
		
			
				|  |  | +    e.preventDefault()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    if (listeners.onDragLeave) {
 | 
	
		
			
				|  |  | +      listeners.onDragLeave(e)
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    clearTimeout(timeout)
 | 
	
		
			
				|  |  | +    removeDragClass()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const pos = {
 | 
	
		
			
				|  |  | +      x: e.clientX,
 | 
	
		
			
				|  |  | +      y: e.clientY
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // text drop support
 | 
	
		
			
				|  |  | +    const text = e.dataTransfer.getData('text')
 | 
	
		
			
				|  |  | +    if (text && listeners.onDropText) {
 | 
	
		
			
				|  |  | +      listeners.onDropText(text, pos)
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // File drop support. The `dataTransfer.items` API supports directories, so we
 | 
	
		
			
				|  |  | +    // use it instead of `dataTransfer.files`, even though it's much more
 | 
	
		
			
				|  |  | +    // complicated to use.
 | 
	
		
			
				|  |  | +    // See: https://github.com/feross/drag-drop/issues/39
 | 
	
		
			
				|  |  | +    if (listeners.onDrop && e.dataTransfer.items) {
 | 
	
		
			
				|  |  | +      const fileList = e.dataTransfer.files
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // Handle directories in Chrome using the proprietary FileSystem API
 | 
	
		
			
				|  |  | +      const items = Array.from(e.dataTransfer.items).filter(item => {
 | 
	
		
			
				|  |  | +        return item.kind === 'file'
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      if (items.length === 0) return
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      parallel(items.map(item => {
 | 
	
		
			
				|  |  | +        return cb => {
 | 
	
		
			
				|  |  | +          processEntry(item.webkitGetAsEntry(), cb)
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }), (err, results) => {
 | 
	
		
			
				|  |  | +        // This catches permission errors with file:// in Chrome. This should never
 | 
	
		
			
				|  |  | +        // throw in production code, so the user does not need to use try-catch.
 | 
	
		
			
				|  |  | +        if (err) throw err
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        const entries = results.flat(Infinity)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        const files = entries.filter(item => {
 | 
	
		
			
				|  |  | +          return item.isFile
 | 
	
		
			
				|  |  | +        })
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        const directories = entries.filter(item => {
 | 
	
		
			
				|  |  | +          return item.isDirectory
 | 
	
		
			
				|  |  | +        })
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        listeners.onDrop(files, pos, fileList, directories)
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return false
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function removeDragClass () {
 | 
	
		
			
				|  |  | +    elem.classList.remove('drag')
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +function processEntry (entry, cb) {
 | 
	
		
			
				|  |  | +  let entries = []
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (entry.isFile) {
 | 
	
		
			
				|  |  | +    entry.file(file => {
 | 
	
		
			
				|  |  | +      file.fullPath = entry.fullPath // preserve pathing for consumer
 | 
	
		
			
				|  |  | +      file.isFile = true
 | 
	
		
			
				|  |  | +      file.isDirectory = false
 | 
	
		
			
				|  |  | +      cb(null, file)
 | 
	
		
			
				|  |  | +    }, err => {
 | 
	
		
			
				|  |  | +      cb(err)
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +  } else if (entry.isDirectory) {
 | 
	
		
			
				|  |  | +    const reader = entry.createReader()
 | 
	
		
			
				|  |  | +    readEntries(reader)
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function readEntries (reader) {
 | 
	
		
			
				|  |  | +    reader.readEntries(entries_ => {
 | 
	
		
			
				|  |  | +      if (entries_.length > 0) {
 | 
	
		
			
				|  |  | +        entries = entries.concat(Array.from(entries_))
 | 
	
		
			
				|  |  | +        readEntries(reader) // continue reading entries until `readEntries` returns no more
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        doneEntries()
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  function doneEntries () {
 | 
	
		
			
				|  |  | +    parallel(entries.map(entry => {
 | 
	
		
			
				|  |  | +      return cb => {
 | 
	
		
			
				|  |  | +        processEntry(entry, cb)
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }), (err, results) => {
 | 
	
		
			
				|  |  | +      if (err) {
 | 
	
		
			
				|  |  | +        cb(err)
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        results.push({
 | 
	
		
			
				|  |  | +          fullPath: entry.fullPath,
 | 
	
		
			
				|  |  | +          name: entry.name,
 | 
	
		
			
				|  |  | +          isFile: false,
 | 
	
		
			
				|  |  | +          isDirectory: true
 | 
	
		
			
				|  |  | +        })
 | 
	
		
			
				|  |  | +        cb(null, results)
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +},{"run-parallel":2}]},{},[])("/")
 | 
	
		
			
				|  |  | +});
 |