+
Cropper.js
+
+
+
+
+
+
+
+
+
+
+
+
+
Cropper.js v1.2.2
+
JavaScript image cropper.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/library/cropperjs/docs/js/cropper.js b/library/cropperjs/docs/js/cropper.js
new file mode 100644
index 000000000..0e837953c
--- /dev/null
+++ b/library/cropperjs/docs/js/cropper.js
@@ -0,0 +1,3766 @@
+/*!
+ * Cropper.js v1.2.2
+ * https://github.com/fengyuanchen/cropperjs
+ *
+ * Copyright (c) 2015-2018 Chen Fengyuan
+ * Released under the MIT license
+ *
+ * Date: 2018-01-03T13:27:18.062Z
+ */
+
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global.Cropper = factory());
+}(this, (function () { 'use strict';
+
+var WINDOW = typeof window !== 'undefined' ? window : {};
+var NAMESPACE = 'cropper';
+
+// Actions
+var ACTION_ALL = 'all';
+var ACTION_CROP = 'crop';
+var ACTION_MOVE = 'move';
+var ACTION_ZOOM = 'zoom';
+var ACTION_EAST = 'e';
+var ACTION_WEST = 'w';
+var ACTION_SOUTH = 's';
+var ACTION_NORTH = 'n';
+var ACTION_NORTH_EAST = 'ne';
+var ACTION_NORTH_WEST = 'nw';
+var ACTION_SOUTH_EAST = 'se';
+var ACTION_SOUTH_WEST = 'sw';
+
+// Classes
+var CLASS_CROP = NAMESPACE + '-crop';
+var CLASS_DISABLED = NAMESPACE + '-disabled';
+var CLASS_HIDDEN = NAMESPACE + '-hidden';
+var CLASS_HIDE = NAMESPACE + '-hide';
+var CLASS_INVISIBLE = NAMESPACE + '-invisible';
+var CLASS_MODAL = NAMESPACE + '-modal';
+var CLASS_MOVE = NAMESPACE + '-move';
+
+// Data keys
+var DATA_ACTION = 'action';
+var DATA_PREVIEW = 'preview';
+
+// Drag modes
+var DRAG_MODE_CROP = 'crop';
+var DRAG_MODE_MOVE = 'move';
+var DRAG_MODE_NONE = 'none';
+
+// Events
+var EVENT_CROP = 'crop';
+var EVENT_CROP_END = 'cropend';
+var EVENT_CROP_MOVE = 'cropmove';
+var EVENT_CROP_START = 'cropstart';
+var EVENT_DBLCLICK = 'dblclick';
+var EVENT_ERROR = 'error';
+var EVENT_LOAD = 'load';
+var EVENT_POINTER_DOWN = WINDOW.PointerEvent ? 'pointerdown' : 'touchstart mousedown';
+var EVENT_POINTER_MOVE = WINDOW.PointerEvent ? 'pointermove' : 'touchmove mousemove';
+var EVENT_POINTER_UP = WINDOW.PointerEvent ? 'pointerup pointercancel' : 'touchend touchcancel mouseup';
+var EVENT_READY = 'ready';
+var EVENT_RESIZE = 'resize';
+var EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll';
+var EVENT_ZOOM = 'zoom';
+
+// RegExps
+var REGEXP_ACTIONS = /^(e|w|s|n|se|sw|ne|nw|all|crop|move|zoom)$/;
+var REGEXP_DATA_URL = /^data:/;
+var REGEXP_DATA_URL_JPEG = /^data:image\/jpeg;base64,/;
+var REGEXP_TAG_NAME = /^(img|canvas)$/i;
+
+var DEFAULTS = {
+ // Define the view mode of the cropper
+ viewMode: 0, // 0, 1, 2, 3
+
+ // Define the dragging mode of the cropper
+ dragMode: DRAG_MODE_CROP, // 'crop', 'move' or 'none'
+
+ // Define the aspect ratio of the crop box
+ aspectRatio: NaN,
+
+ // An object with the previous cropping result data
+ data: null,
+
+ // A selector for adding extra containers to preview
+ preview: '',
+
+ // Re-render the cropper when resize the window
+ responsive: true,
+
+ // Restore the cropped area after resize the window
+ restore: true,
+
+ // Check if the current image is a cross-origin image
+ checkCrossOrigin: true,
+
+ // Check the current image's Exif Orientation information
+ checkOrientation: true,
+
+ // Show the black modal
+ modal: true,
+
+ // Show the dashed lines for guiding
+ guides: true,
+
+ // Show the center indicator for guiding
+ center: true,
+
+ // Show the white modal to highlight the crop box
+ highlight: true,
+
+ // Show the grid background
+ background: true,
+
+ // Enable to crop the image automatically when initialize
+ autoCrop: true,
+
+ // Define the percentage of automatic cropping area when initializes
+ autoCropArea: 0.8,
+
+ // Enable to move the image
+ movable: true,
+
+ // Enable to rotate the image
+ rotatable: true,
+
+ // Enable to scale the image
+ scalable: true,
+
+ // Enable to zoom the image
+ zoomable: true,
+
+ // Enable to zoom the image by dragging touch
+ zoomOnTouch: true,
+
+ // Enable to zoom the image by wheeling mouse
+ zoomOnWheel: true,
+
+ // Define zoom ratio when zoom the image by wheeling mouse
+ wheelZoomRatio: 0.1,
+
+ // Enable to move the crop box
+ cropBoxMovable: true,
+
+ // Enable to resize the crop box
+ cropBoxResizable: true,
+
+ // Toggle drag mode between "crop" and "move" when click twice on the cropper
+ toggleDragModeOnDblclick: true,
+
+ // Size limitation
+ minCanvasWidth: 0,
+ minCanvasHeight: 0,
+ minCropBoxWidth: 0,
+ minCropBoxHeight: 0,
+ minContainerWidth: 200,
+ minContainerHeight: 100,
+
+ // Shortcuts of events
+ ready: null,
+ cropstart: null,
+ cropmove: null,
+ cropend: null,
+ crop: null,
+ zoom: null
+};
+
+var TEMPLATE = '
' + '
' + '
' + '
' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + '
' + '
';
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
+ return typeof obj;
+} : function (obj) {
+ return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
+};
+
+
+
+
+
+
+
+
+
+
+
+var classCallCheck = function (instance, Constructor) {
+ if (!(instance instanceof Constructor)) {
+ throw new TypeError("Cannot call a class as a function");
+ }
+};
+
+var createClass = function () {
+ function defineProperties(target, props) {
+ for (var i = 0; i < props.length; i++) {
+ var descriptor = props[i];
+ descriptor.enumerable = descriptor.enumerable || false;
+ descriptor.configurable = true;
+ if ("value" in descriptor) descriptor.writable = true;
+ Object.defineProperty(target, descriptor.key, descriptor);
+ }
+ }
+
+ return function (Constructor, protoProps, staticProps) {
+ if (protoProps) defineProperties(Constructor.prototype, protoProps);
+ if (staticProps) defineProperties(Constructor, staticProps);
+ return Constructor;
+ };
+}();
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+var toConsumableArray = function (arr) {
+ if (Array.isArray(arr)) {
+ for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
+
+ return arr2;
+ } else {
+ return Array.from(arr);
+ }
+};
+
+/**
+ * Check if the given value is not a number.
+ */
+var isNaN = Number.isNaN || WINDOW.isNaN;
+
+/**
+ * Check if the given value is a number.
+ * @param {*} value - The value to check.
+ * @returns {boolean} Returns `true` if the given value is a number, else `false`.
+ */
+function isNumber(value) {
+ return typeof value === 'number' && !isNaN(value);
+}
+
+/**
+ * Check if the given value is undefined.
+ * @param {*} value - The value to check.
+ * @returns {boolean} Returns `true` if the given value is undefined, else `false`.
+ */
+function isUndefined(value) {
+ return typeof value === 'undefined';
+}
+
+/**
+ * Check if the given value is an object.
+ * @param {*} value - The value to check.
+ * @returns {boolean} Returns `true` if the given value is an object, else `false`.
+ */
+function isObject(value) {
+ return (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && value !== null;
+}
+
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+/**
+ * Check if the given value is a plain object.
+ * @param {*} value - The value to check.
+ * @returns {boolean} Returns `true` if the given value is a plain object, else `false`.
+ */
+
+function isPlainObject(value) {
+ if (!isObject(value)) {
+ return false;
+ }
+
+ try {
+ var _constructor = value.constructor;
+ var prototype = _constructor.prototype;
+
+
+ return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');
+ } catch (e) {
+ return false;
+ }
+}
+
+/**
+ * Check if the given value is a function.
+ * @param {*} value - The value to check.
+ * @returns {boolean} Returns `true` if the given value is a function, else `false`.
+ */
+function isFunction(value) {
+ return typeof value === 'function';
+}
+
+/**
+ * Iterate the given data.
+ * @param {*} data - The data to iterate.
+ * @param {Function} callback - The process function for each element.
+ * @returns {*} The original data.
+ */
+function each(data, callback) {
+ if (data && isFunction(callback)) {
+ if (Array.isArray(data) || isNumber(data.length) /* array-like */) {
+ var length = data.length;
+
+ var i = void 0;
+
+ for (i = 0; i < length; i += 1) {
+ if (callback.call(data, data[i], i, data) === false) {
+ break;
+ }
+ }
+ } else if (isObject(data)) {
+ Object.keys(data).forEach(function (key) {
+ callback.call(data, data[key], key, data);
+ });
+ }
+ }
+
+ return data;
+}
+
+/**
+ * Extend the given object.
+ * @param {*} obj - The object to be extended.
+ * @param {*} args - The rest objects which will be merged to the first object.
+ * @returns {Object} The extended object.
+ */
+function extend(obj) {
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = arguments[_key];
+ }
+
+ if (isObject(obj) && args.length > 0) {
+ if (Object.assign) {
+ return Object.assign.apply(Object, [obj].concat(args));
+ }
+
+ args.forEach(function (arg) {
+ if (isObject(arg)) {
+ Object.keys(arg).forEach(function (key) {
+ obj[key] = arg[key];
+ });
+ }
+ });
+ }
+
+ return obj;
+}
+
+/**
+ * Takes a function and returns a new one that will always have a particular context.
+ * @param {Function} fn - The target function.
+ * @param {Object} context - The new context for the function.
+ * @returns {boolean} The new function.
+ */
+function proxy(fn, context) {
+ for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
+ args[_key2 - 2] = arguments[_key2];
+ }
+
+ return function () {
+ for (var _len3 = arguments.length, args2 = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
+ args2[_key3] = arguments[_key3];
+ }
+
+ return fn.apply(context, args.concat(args2));
+ };
+}
+
+var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/i;
+
+/**
+ * Normalize decimal number.
+ * Check out {@link http://0.30000000000000004.com/ }
+ * @param {number} value - The value to normalize.
+ * @param {number} [times=100000000000] - The times for normalizing.
+ * @returns {number} Returns the normalized number.
+ */
+function normalizeDecimalNumber(value) {
+ var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000;
+
+ return REGEXP_DECIMALS.test(value) ? Math.round(value * times) / times : value;
+}
+
+var REGEXP_SUFFIX = /^(width|height|left|top|marginLeft|marginTop)$/;
+
+/**
+ * Apply styles to the given element.
+ * @param {Element} element - The target element.
+ * @param {Object} styles - The styles for applying.
+ */
+function setStyle(element, styles) {
+ var style = element.style;
+
+
+ each(styles, function (value, property) {
+ if (REGEXP_SUFFIX.test(property) && isNumber(value)) {
+ value += 'px';
+ }
+
+ style[property] = value;
+ });
+}
+
+/**
+ * Check if the given element has a special class.
+ * @param {Element} element - The element to check.
+ * @param {string} value - The class to search.
+ * @returns {boolean} Returns `true` if the special class was found.
+ */
+function hasClass(element, value) {
+ return element.classList ? element.classList.contains(value) : element.className.indexOf(value) > -1;
+}
+
+/**
+ * Add classes to the given element.
+ * @param {Element} element - The target element.
+ * @param {string} value - The classes to be added.
+ */
+function addClass(element, value) {
+ if (!value) {
+ return;
+ }
+
+ if (isNumber(element.length)) {
+ each(element, function (elem) {
+ addClass(elem, value);
+ });
+ return;
+ }
+
+ if (element.classList) {
+ element.classList.add(value);
+ return;
+ }
+
+ var className = element.className.trim();
+
+ if (!className) {
+ element.className = value;
+ } else if (className.indexOf(value) < 0) {
+ element.className = className + ' ' + value;
+ }
+}
+
+/**
+ * Remove classes from the given element.
+ * @param {Element} element - The target element.
+ * @param {string} value - The classes to be removed.
+ */
+function removeClass(element, value) {
+ if (!value) {
+ return;
+ }
+
+ if (isNumber(element.length)) {
+ each(element, function (elem) {
+ removeClass(elem, value);
+ });
+ return;
+ }
+
+ if (element.classList) {
+ element.classList.remove(value);
+ return;
+ }
+
+ if (element.className.indexOf(value) >= 0) {
+ element.className = element.className.replace(value, '');
+ }
+}
+
+/**
+ * Add or remove classes from the given element.
+ * @param {Element} element - The target element.
+ * @param {string} value - The classes to be toggled.
+ * @param {boolean} added - Add only.
+ */
+function toggleClass(element, value, added) {
+ if (!value) {
+ return;
+ }
+
+ if (isNumber(element.length)) {
+ each(element, function (elem) {
+ toggleClass(elem, value, added);
+ });
+ return;
+ }
+
+ // IE10-11 doesn't support the second parameter of `classList.toggle`
+ if (added) {
+ addClass(element, value);
+ } else {
+ removeClass(element, value);
+ }
+}
+
+var REGEXP_HYPHENATE = /([a-z\d])([A-Z])/g;
+
+/**
+ * Hyphenate the given value.
+ * @param {string} value - The value to hyphenate.
+ * @returns {string} The hyphenated value.
+ */
+function hyphenate(value) {
+ return value.replace(REGEXP_HYPHENATE, '$1-$2').toLowerCase();
+}
+
+/**
+ * Get data from the given element.
+ * @param {Element} element - The target element.
+ * @param {string} name - The data key to get.
+ * @returns {string} The data value.
+ */
+function getData(element, name) {
+ if (isObject(element[name])) {
+ return element[name];
+ } else if (element.dataset) {
+ return element.dataset[name];
+ }
+
+ return element.getAttribute('data-' + hyphenate(name));
+}
+
+/**
+ * Set data to the given element.
+ * @param {Element} element - The target element.
+ * @param {string} name - The data key to set.
+ * @param {string} data - The data value.
+ */
+function setData(element, name, data) {
+ if (isObject(data)) {
+ element[name] = data;
+ } else if (element.dataset) {
+ element.dataset[name] = data;
+ } else {
+ element.setAttribute('data-' + hyphenate(name), data);
+ }
+}
+
+/**
+ * Remove data from the given element.
+ * @param {Element} element - The target element.
+ * @param {string} name - The data key to remove.
+ */
+function removeData(element, name) {
+ if (isObject(element[name])) {
+ try {
+ delete element[name];
+ } catch (e) {
+ element[name] = null;
+ }
+ } else if (element.dataset) {
+ // #128 Safari not allows to delete dataset property
+ try {
+ delete element.dataset[name];
+ } catch (e) {
+ element.dataset[name] = null;
+ }
+ } else {
+ element.removeAttribute('data-' + hyphenate(name));
+ }
+}
+
+var REGEXP_SPACES = /\s+/;
+
+/**
+ * Remove event listener from the target element.
+ * @param {Element} element - The event target.
+ * @param {string} type - The event type(s).
+ * @param {Function} listener - The event listener.
+ * @param {Object} options - The event options.
+ */
+function removeListener(element, type, listener) {
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
+
+ if (!isFunction(listener)) {
+ return;
+ }
+
+ var types = type.trim().split(REGEXP_SPACES);
+
+ if (types.length > 1) {
+ each(types, function (t) {
+ removeListener(element, t, listener, options);
+ });
+ return;
+ }
+
+ if (element.removeEventListener) {
+ element.removeEventListener(type, listener, options);
+ } else if (element.detachEvent) {
+ element.detachEvent('on' + type, listener);
+ }
+}
+
+/**
+ * Add event listener to the target element.
+ * @param {Element} element - The event target.
+ * @param {string} type - The event type(s).
+ * @param {Function} listener - The event listener.
+ * @param {Object} options - The event options.
+ */
+function addListener(element, type, _listener) {
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
+
+ if (!isFunction(_listener)) {
+ return;
+ }
+
+ var types = type.trim().split(REGEXP_SPACES);
+
+ if (types.length > 1) {
+ each(types, function (t) {
+ addListener(element, t, _listener, options);
+ });
+ return;
+ }
+
+ if (options.once) {
+ var originalListener = _listener;
+
+ _listener = function listener() {
+ for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
+ args[_key4] = arguments[_key4];
+ }
+
+ removeListener(element, type, _listener, options);
+ return originalListener.apply(element, args);
+ };
+ }
+
+ if (element.addEventListener) {
+ element.addEventListener(type, _listener, options);
+ } else if (element.attachEvent) {
+ element.attachEvent('on' + type, _listener);
+ }
+}
+
+/**
+ * Dispatch event on the target element.
+ * @param {Element} element - The event target.
+ * @param {string} type - The event type(s).
+ * @param {Object} data - The additional event data.
+ * @returns {boolean} Indicate if the event is default prevented or not.
+ */
+function dispatchEvent(element, type, data) {
+ if (element.dispatchEvent) {
+ var event = void 0;
+
+ // Event and CustomEvent on IE9-11 are global objects, not constructors
+ if (isFunction(Event) && isFunction(CustomEvent)) {
+ if (isUndefined(data)) {
+ event = new Event(type, {
+ bubbles: true,
+ cancelable: true
+ });
+ } else {
+ event = new CustomEvent(type, {
+ detail: data,
+ bubbles: true,
+ cancelable: true
+ });
+ }
+ } else if (isUndefined(data)) {
+ event = document.createEvent('Event');
+ event.initEvent(type, true, true);
+ } else {
+ event = document.createEvent('CustomEvent');
+ event.initCustomEvent(type, true, true, data);
+ }
+
+ // IE9+
+ return element.dispatchEvent(event);
+ } else if (element.fireEvent) {
+ // IE6-10 (native events only)
+ return element.fireEvent('on' + type);
+ }
+
+ return true;
+}
+
+/**
+ * Get the offset base on the document.
+ * @param {Element} element - The target element.
+ * @returns {Object} The offset data.
+ */
+function getOffset(element) {
+ var doc = document.documentElement;
+ var box = element.getBoundingClientRect();
+
+ return {
+ left: box.left + ((window.scrollX || doc && doc.scrollLeft || 0) - (doc && doc.clientLeft || 0)),
+ top: box.top + ((window.scrollY || doc && doc.scrollTop || 0) - (doc && doc.clientTop || 0))
+ };
+}
+
+/**
+ * Empty an element.
+ * @param {Element} element - The element to empty.
+ */
+function empty(element) {
+ while (element.firstChild) {
+ element.removeChild(element.firstChild);
+ }
+}
+
+var location = WINDOW.location;
+
+var REGEXP_ORIGINS = /^(https?:)\/\/([^:/?#]+):?(\d*)/i;
+
+/**
+ * Check if the given URL is a cross origin URL.
+ * @param {string} url - The target URL.
+ * @returns {boolean} Returns `true` if the given URL is a cross origin URL, else `false`.
+ */
+function isCrossOriginURL(url) {
+ var parts = url.match(REGEXP_ORIGINS);
+
+ return parts && (parts[1] !== location.protocol || parts[2] !== location.hostname || parts[3] !== location.port);
+}
+
+/**
+ * Add timestamp to the given URL.
+ * @param {string} url - The target URL.
+ * @returns {string} The result URL.
+ */
+function addTimestamp(url) {
+ var timestamp = 'timestamp=' + new Date().getTime();
+
+ return url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp;
+}
+
+/**
+ * Get transforms base on the given object.
+ * @param {Object} obj - The target object.
+ * @returns {string} A string contains transform values.
+ */
+function getTransforms(_ref) {
+ var rotate = _ref.rotate,
+ scaleX = _ref.scaleX,
+ scaleY = _ref.scaleY,
+ translateX = _ref.translateX,
+ translateY = _ref.translateY;
+
+ var values = [];
+
+ if (isNumber(translateX) && translateX !== 0) {
+ values.push('translateX(' + translateX + 'px)');
+ }
+
+ if (isNumber(translateY) && translateY !== 0) {
+ values.push('translateY(' + translateY + 'px)');
+ }
+
+ // Rotate should come first before scale to match orientation transform
+ if (isNumber(rotate) && rotate !== 0) {
+ values.push('rotate(' + rotate + 'deg)');
+ }
+
+ if (isNumber(scaleX) && scaleX !== 1) {
+ values.push('scaleX(' + scaleX + ')');
+ }
+
+ if (isNumber(scaleY) && scaleY !== 1) {
+ values.push('scaleY(' + scaleY + ')');
+ }
+
+ var transform = values.length ? values.join(' ') : 'none';
+
+ return {
+ WebkitTransform: transform,
+ msTransform: transform,
+ transform: transform
+ };
+}
+
+var navigator = WINDOW.navigator;
+
+var IS_SAFARI_OR_UIWEBVIEW = navigator && /(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(navigator.userAgent);
+
+/**
+ * Get an image's natural sizes.
+ * @param {string} image - The target image.
+ * @param {Function} callback - The callback function.
+ */
+function getImageNaturalSizes(image, callback) {
+ // Modern browsers (except Safari)
+ if (image.naturalWidth && !IS_SAFARI_OR_UIWEBVIEW) {
+ callback(image.naturalWidth, image.naturalHeight);
+ return;
+ }
+
+ var newImage = document.createElement('img');
+ var body = document.body || document.documentElement;
+
+ newImage.onload = function () {
+ callback(newImage.width, newImage.height);
+
+ if (!IS_SAFARI_OR_UIWEBVIEW) {
+ body.removeChild(newImage);
+ }
+ };
+
+ newImage.src = image.src;
+
+ // iOS Safari will convert the image automatically
+ // with its orientation once append it into DOM (#279)
+ if (!IS_SAFARI_OR_UIWEBVIEW) {
+ newImage.style.cssText = 'left:0;' + 'max-height:none!important;' + 'max-width:none!important;' + 'min-height:0!important;' + 'min-width:0!important;' + 'opacity:0;' + 'position:absolute;' + 'top:0;' + 'z-index:-1;';
+ body.appendChild(newImage);
+ }
+}
+
+/**
+ * Get the max ratio of a group of pointers.
+ * @param {string} pointers - The target pointers.
+ * @returns {number} The result ratio.
+ */
+function getMaxZoomRatio(pointers) {
+ var pointers2 = extend({}, pointers);
+ var ratios = [];
+
+ each(pointers, function (pointer, pointerId) {
+ delete pointers2[pointerId];
+
+ each(pointers2, function (pointer2) {
+ var x1 = Math.abs(pointer.startX - pointer2.startX);
+ var y1 = Math.abs(pointer.startY - pointer2.startY);
+ var x2 = Math.abs(pointer.endX - pointer2.endX);
+ var y2 = Math.abs(pointer.endY - pointer2.endY);
+ var z1 = Math.sqrt(x1 * x1 + y1 * y1);
+ var z2 = Math.sqrt(x2 * x2 + y2 * y2);
+ var ratio = (z2 - z1) / z1;
+
+ ratios.push(ratio);
+ });
+ });
+
+ ratios.sort(function (a, b) {
+ return Math.abs(a) < Math.abs(b);
+ });
+
+ return ratios[0];
+}
+
+/**
+ * Get a pointer from an event object.
+ * @param {Object} event - The target event object.
+ * @param {boolean} endOnly - Indicates if only returns the end point coordinate or not.
+ * @returns {Object} The result pointer contains start and/or end point coordinates.
+ */
+function getPointer(_ref2, endOnly) {
+ var pageX = _ref2.pageX,
+ pageY = _ref2.pageY;
+
+ var end = {
+ endX: pageX,
+ endY: pageY
+ };
+
+ if (endOnly) {
+ return end;
+ }
+
+ return extend({
+ startX: pageX,
+ startY: pageY
+ }, end);
+}
+
+/**
+ * Get the center point coordinate of a group of pointers.
+ * @param {Object} pointers - The target pointers.
+ * @returns {Object} The center point coordinate.
+ */
+function getPointersCenter(pointers) {
+ var pageX = 0;
+ var pageY = 0;
+ var count = 0;
+
+ each(pointers, function (_ref3) {
+ var startX = _ref3.startX,
+ startY = _ref3.startY;
+
+ pageX += startX;
+ pageY += startY;
+ count += 1;
+ });
+
+ pageX /= count;
+ pageY /= count;
+
+ return {
+ pageX: pageX,
+ pageY: pageY
+ };
+}
+
+/**
+ * Check if the given value is a finite number.
+ */
+var isFinite = Number.isFinite || WINDOW.isFinite;
+
+/**
+ * Get the max sizes in a rectangle under the given aspect ratio.
+ * @param {Object} data - The original sizes.
+ * @returns {Object} The result sizes.
+ */
+function getContainSizes(_ref4) {
+ var aspectRatio = _ref4.aspectRatio,
+ height = _ref4.height,
+ width = _ref4.width;
+
+ var isValidNumber = function isValidNumber(value) {
+ return isFinite(value) && value > 0;
+ };
+
+ if (isValidNumber(width) && isValidNumber(height)) {
+ if (height * aspectRatio > width) {
+ height = width / aspectRatio;
+ } else {
+ width = height * aspectRatio;
+ }
+ } else if (isValidNumber(width)) {
+ height = width / aspectRatio;
+ } else if (isValidNumber(height)) {
+ width = height * aspectRatio;
+ }
+
+ return {
+ width: width,
+ height: height
+ };
+}
+
+/**
+ * Get the new sizes of a rectangle after rotated.
+ * @param {Object} data - The original sizes.
+ * @returns {Object} The result sizes.
+ */
+function getRotatedSizes(_ref5) {
+ var width = _ref5.width,
+ height = _ref5.height,
+ degree = _ref5.degree;
+
+ degree = Math.abs(degree) % 180;
+
+ if (degree === 90) {
+ return {
+ width: height,
+ height: width
+ };
+ }
+
+ var arc = degree % 90 * Math.PI / 180;
+ var sinArc = Math.sin(arc);
+ var cosArc = Math.cos(arc);
+ var newWidth = width * cosArc + height * sinArc;
+ var newHeight = width * sinArc + height * cosArc;
+
+ return degree > 90 ? {
+ width: newHeight,
+ height: newWidth
+ } : {
+ width: newWidth,
+ height: newHeight
+ };
+}
+
+/**
+ * Get a canvas which drew the given image.
+ * @param {HTMLImageElement} image - The image for drawing.
+ * @param {Object} imageData - The image data.
+ * @param {Object} canvasData - The canvas data.
+ * @param {Object} options - The options.
+ * @returns {HTMLCanvasElement} The result canvas.
+ */
+function getSourceCanvas(image, _ref6, _ref7, _ref8) {
+ var imageNaturalWidth = _ref6.naturalWidth,
+ imageNaturalHeight = _ref6.naturalHeight,
+ _ref6$rotate = _ref6.rotate,
+ rotate = _ref6$rotate === undefined ? 0 : _ref6$rotate,
+ _ref6$scaleX = _ref6.scaleX,
+ scaleX = _ref6$scaleX === undefined ? 1 : _ref6$scaleX,
+ _ref6$scaleY = _ref6.scaleY,
+ scaleY = _ref6$scaleY === undefined ? 1 : _ref6$scaleY;
+ var aspectRatio = _ref7.aspectRatio,
+ naturalWidth = _ref7.naturalWidth,
+ naturalHeight = _ref7.naturalHeight;
+ var _ref8$fillColor = _ref8.fillColor,
+ fillColor = _ref8$fillColor === undefined ? 'transparent' : _ref8$fillColor,
+ _ref8$imageSmoothingE = _ref8.imageSmoothingEnabled,
+ imageSmoothingEnabled = _ref8$imageSmoothingE === undefined ? true : _ref8$imageSmoothingE,
+ _ref8$imageSmoothingQ = _ref8.imageSmoothingQuality,
+ imageSmoothingQuality = _ref8$imageSmoothingQ === undefined ? 'low' : _ref8$imageSmoothingQ,
+ _ref8$maxWidth = _ref8.maxWidth,
+ maxWidth = _ref8$maxWidth === undefined ? Infinity : _ref8$maxWidth,
+ _ref8$maxHeight = _ref8.maxHeight,
+ maxHeight = _ref8$maxHeight === undefined ? Infinity : _ref8$maxHeight,
+ _ref8$minWidth = _ref8.minWidth,
+ minWidth = _ref8$minWidth === undefined ? 0 : _ref8$minWidth,
+ _ref8$minHeight = _ref8.minHeight,
+ minHeight = _ref8$minHeight === undefined ? 0 : _ref8$minHeight;
+
+ var canvas = document.createElement('canvas');
+ var context = canvas.getContext('2d');
+ var maxSizes = getContainSizes({
+ aspectRatio: aspectRatio,
+ width: maxWidth,
+ height: maxHeight
+ });
+ var minSizes = getContainSizes({
+ aspectRatio: aspectRatio,
+ width: minWidth,
+ height: minHeight
+ });
+ var width = Math.min(maxSizes.width, Math.max(minSizes.width, naturalWidth));
+ var height = Math.min(maxSizes.height, Math.max(minSizes.height, naturalHeight));
+ var params = [-imageNaturalWidth / 2, -imageNaturalHeight / 2, imageNaturalWidth, imageNaturalHeight];
+
+ canvas.width = normalizeDecimalNumber(width);
+ canvas.height = normalizeDecimalNumber(height);
+ context.fillStyle = fillColor;
+ context.fillRect(0, 0, width, height);
+ context.save();
+ context.translate(width / 2, height / 2);
+ context.rotate(rotate * Math.PI / 180);
+ context.scale(scaleX, scaleY);
+ context.imageSmoothingEnabled = imageSmoothingEnabled;
+ context.imageSmoothingQuality = imageSmoothingQuality;
+ context.drawImage.apply(context, [image].concat(toConsumableArray(params.map(function (param) {
+ return Math.floor(normalizeDecimalNumber(param));
+ }))));
+ context.restore();
+ return canvas;
+}
+
+var fromCharCode = String.fromCharCode;
+
+/**
+ * Get string from char code in data view.
+ * @param {DataView} dataView - The data view for read.
+ * @param {number} start - The start index.
+ * @param {number} length - The read length.
+ * @returns {string} The read result.
+ */
+
+function getStringFromCharCode(dataView, start, length) {
+ var str = '';
+ var i = void 0;
+
+ length += start;
+
+ for (i = start; i < length; i += 1) {
+ str += fromCharCode(dataView.getUint8(i));
+ }
+
+ return str;
+}
+
+var REGEXP_DATA_URL_HEAD = /^data:.*,/;
+
+/**
+ * Transform Data URL to array buffer.
+ * @param {string} dataURL - The Data URL to transform.
+ * @returns {ArrayBuffer} The result array buffer.
+ */
+function dataURLToArrayBuffer(dataURL) {
+ var base64 = dataURL.replace(REGEXP_DATA_URL_HEAD, '');
+ var binary = atob(base64);
+ var arrayBuffer = new ArrayBuffer(binary.length);
+ var uint8 = new Uint8Array(arrayBuffer);
+
+ each(uint8, function (value, i) {
+ uint8[i] = binary.charCodeAt(i);
+ });
+
+ return arrayBuffer;
+}
+
+/**
+ * Transform array buffer to Data URL.
+ * @param {ArrayBuffer} arrayBuffer - The array buffer to transform.
+ * @param {string} mimeType - The mime type of the Data URL.
+ * @returns {string} The result Data URL.
+ */
+function arrayBufferToDataURL(arrayBuffer, mimeType) {
+ var uint8 = new Uint8Array(arrayBuffer);
+ var data = '';
+
+ // TypedArray.prototype.forEach is not supported in some browsers.
+ each(uint8, function (value) {
+ data += fromCharCode(value);
+ });
+
+ return 'data:' + mimeType + ';base64,' + btoa(data);
+}
+
+/**
+ * Get orientation value from given array buffer.
+ * @param {ArrayBuffer} arrayBuffer - The array buffer to read.
+ * @returns {number} The read orientation value.
+ */
+function getOrientation(arrayBuffer) {
+ var dataView = new DataView(arrayBuffer);
+ var orientation = void 0;
+ var littleEndian = void 0;
+ var app1Start = void 0;
+ var ifdStart = void 0;
+
+ // Only handle JPEG image (start by 0xFFD8)
+ if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
+ var length = dataView.byteLength;
+ var offset = 2;
+
+ while (offset < length) {
+ if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
+ app1Start = offset;
+ break;
+ }
+
+ offset += 1;
+ }
+ }
+
+ if (app1Start) {
+ var exifIDCode = app1Start + 4;
+ var tiffOffset = app1Start + 10;
+
+ if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
+ var endianness = dataView.getUint16(tiffOffset);
+
+ littleEndian = endianness === 0x4949;
+
+ if (littleEndian || endianness === 0x4D4D /* bigEndian */) {
+ if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
+ var firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
+
+ if (firstIFDOffset >= 0x00000008) {
+ ifdStart = tiffOffset + firstIFDOffset;
+ }
+ }
+ }
+ }
+ }
+
+ if (ifdStart) {
+ var _length = dataView.getUint16(ifdStart, littleEndian);
+ var _offset = void 0;
+ var i = void 0;
+
+ for (i = 0; i < _length; i += 1) {
+ _offset = ifdStart + i * 12 + 2;
+
+ if (dataView.getUint16(_offset, littleEndian) === 0x0112 /* Orientation */) {
+ // 8 is the offset of the current tag's value
+ _offset += 8;
+
+ // Get the original orientation value
+ orientation = dataView.getUint16(_offset, littleEndian);
+
+ // Override the orientation with its default value
+ dataView.setUint16(_offset, 1, littleEndian);
+ break;
+ }
+ }
+ }
+
+ return orientation;
+}
+
+/**
+ * Parse Exif Orientation value.
+ * @param {number} orientation - The orientation to parse.
+ * @returns {Object} The parsed result.
+ */
+function parseOrientation(orientation) {
+ var rotate = 0;
+ var scaleX = 1;
+ var scaleY = 1;
+
+ switch (orientation) {
+ // Flip horizontal
+ case 2:
+ scaleX = -1;
+ break;
+
+ // Rotate left 180°
+ case 3:
+ rotate = -180;
+ break;
+
+ // Flip vertical
+ case 4:
+ scaleY = -1;
+ break;
+
+ // Flip vertical and rotate right 90°
+ case 5:
+ rotate = 90;
+ scaleY = -1;
+ break;
+
+ // Rotate right 90°
+ case 6:
+ rotate = 90;
+ break;
+
+ // Flip horizontal and rotate right 90°
+ case 7:
+ rotate = 90;
+ scaleX = -1;
+ break;
+
+ // Rotate left 90°
+ case 8:
+ rotate = -90;
+ break;
+
+ default:
+ }
+
+ return {
+ rotate: rotate,
+ scaleX: scaleX,
+ scaleY: scaleY
+ };
+}
+
+var render = {
+ render: function render() {
+ this.initContainer();
+ this.initCanvas();
+ this.initCropBox();
+ this.renderCanvas();
+
+ if (this.cropped) {
+ this.renderCropBox();
+ }
+ },
+ initContainer: function initContainer() {
+ var element = this.element,
+ options = this.options,
+ container = this.container,
+ cropper = this.cropper;
+
+
+ addClass(cropper, CLASS_HIDDEN);
+ removeClass(element, CLASS_HIDDEN);
+
+ var containerData = {
+ width: Math.max(container.offsetWidth, Number(options.minContainerWidth) || 200),
+ height: Math.max(container.offsetHeight, Number(options.minContainerHeight) || 100)
+ };
+
+ this.containerData = containerData;
+
+ setStyle(cropper, {
+ width: containerData.width,
+ height: containerData.height
+ });
+
+ addClass(element, CLASS_HIDDEN);
+ removeClass(cropper, CLASS_HIDDEN);
+ },
+
+
+ // Canvas (image wrapper)
+ initCanvas: function initCanvas() {
+ var containerData = this.containerData,
+ imageData = this.imageData;
+ var viewMode = this.options.viewMode;
+
+ var rotated = Math.abs(imageData.rotate) % 180 === 90;
+ var naturalWidth = rotated ? imageData.naturalHeight : imageData.naturalWidth;
+ var naturalHeight = rotated ? imageData.naturalWidth : imageData.naturalHeight;
+ var aspectRatio = naturalWidth / naturalHeight;
+ var canvasWidth = containerData.width;
+ var canvasHeight = containerData.height;
+
+ if (containerData.height * aspectRatio > containerData.width) {
+ if (viewMode === 3) {
+ canvasWidth = containerData.height * aspectRatio;
+ } else {
+ canvasHeight = containerData.width / aspectRatio;
+ }
+ } else if (viewMode === 3) {
+ canvasHeight = containerData.width / aspectRatio;
+ } else {
+ canvasWidth = containerData.height * aspectRatio;
+ }
+
+ var canvasData = {
+ aspectRatio: aspectRatio,
+ naturalWidth: naturalWidth,
+ naturalHeight: naturalHeight,
+ width: canvasWidth,
+ height: canvasHeight
+ };
+
+ canvasData.left = (containerData.width - canvasWidth) / 2;
+ canvasData.top = (containerData.height - canvasHeight) / 2;
+ canvasData.oldLeft = canvasData.left;
+ canvasData.oldTop = canvasData.top;
+
+ this.canvasData = canvasData;
+ this.limited = viewMode === 1 || viewMode === 2;
+ this.limitCanvas(true, true);
+ this.initialImageData = extend({}, imageData);
+ this.initialCanvasData = extend({}, canvasData);
+ },
+ limitCanvas: function limitCanvas(sizeLimited, positionLimited) {
+ var options = this.options,
+ containerData = this.containerData,
+ canvasData = this.canvasData,
+ cropBoxData = this.cropBoxData;
+ var viewMode = options.viewMode;
+ var aspectRatio = canvasData.aspectRatio;
+
+ var cropped = this.cropped && cropBoxData;
+
+ if (sizeLimited) {
+ var minCanvasWidth = Number(options.minCanvasWidth) || 0;
+ var minCanvasHeight = Number(options.minCanvasHeight) || 0;
+
+ if (viewMode > 1) {
+ minCanvasWidth = Math.max(minCanvasWidth, containerData.width);
+ minCanvasHeight = Math.max(minCanvasHeight, containerData.height);
+
+ if (viewMode === 3) {
+ if (minCanvasHeight * aspectRatio > minCanvasWidth) {
+ minCanvasWidth = minCanvasHeight * aspectRatio;
+ } else {
+ minCanvasHeight = minCanvasWidth / aspectRatio;
+ }
+ }
+ } else if (viewMode > 0) {
+ if (minCanvasWidth) {
+ minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBoxData.width : 0);
+ } else if (minCanvasHeight) {
+ minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBoxData.height : 0);
+ } else if (cropped) {
+ minCanvasWidth = cropBoxData.width;
+ minCanvasHeight = cropBoxData.height;
+
+ if (minCanvasHeight * aspectRatio > minCanvasWidth) {
+ minCanvasWidth = minCanvasHeight * aspectRatio;
+ } else {
+ minCanvasHeight = minCanvasWidth / aspectRatio;
+ }
+ }
+ }
+
+ var _getContainSizes = getContainSizes({
+ aspectRatio: aspectRatio,
+ width: minCanvasWidth,
+ height: minCanvasHeight
+ });
+
+ minCanvasWidth = _getContainSizes.width;
+ minCanvasHeight = _getContainSizes.height;
+
+
+ canvasData.minWidth = minCanvasWidth;
+ canvasData.minHeight = minCanvasHeight;
+ canvasData.maxWidth = Infinity;
+ canvasData.maxHeight = Infinity;
+ }
+
+ if (positionLimited) {
+ if (viewMode) {
+ var newCanvasLeft = containerData.width - canvasData.width;
+ var newCanvasTop = containerData.height - canvasData.height;
+
+ canvasData.minLeft = Math.min(0, newCanvasLeft);
+ canvasData.minTop = Math.min(0, newCanvasTop);
+ canvasData.maxLeft = Math.max(0, newCanvasLeft);
+ canvasData.maxTop = Math.max(0, newCanvasTop);
+
+ if (cropped && this.limited) {
+ canvasData.minLeft = Math.min(cropBoxData.left, cropBoxData.left + (cropBoxData.width - canvasData.width));
+ canvasData.minTop = Math.min(cropBoxData.top, cropBoxData.top + (cropBoxData.height - canvasData.height));
+ canvasData.maxLeft = cropBoxData.left;
+ canvasData.maxTop = cropBoxData.top;
+
+ if (viewMode === 2) {
+ if (canvasData.width >= containerData.width) {
+ canvasData.minLeft = Math.min(0, newCanvasLeft);
+ canvasData.maxLeft = Math.max(0, newCanvasLeft);
+ }
+
+ if (canvasData.height >= containerData.height) {
+ canvasData.minTop = Math.min(0, newCanvasTop);
+ canvasData.maxTop = Math.max(0, newCanvasTop);
+ }
+ }
+ }
+ } else {
+ canvasData.minLeft = -canvasData.width;
+ canvasData.minTop = -canvasData.height;
+ canvasData.maxLeft = containerData.width;
+ canvasData.maxTop = containerData.height;
+ }
+ }
+ },
+ renderCanvas: function renderCanvas(changed, transformed) {
+ var canvasData = this.canvasData,
+ imageData = this.imageData;
+
+
+ if (transformed) {
+ var _getRotatedSizes = getRotatedSizes({
+ width: imageData.naturalWidth * Math.abs(imageData.scaleX || 1),
+ height: imageData.naturalHeight * Math.abs(imageData.scaleY || 1),
+ degree: imageData.rotate || 0
+ }),
+ naturalWidth = _getRotatedSizes.width,
+ naturalHeight = _getRotatedSizes.height;
+
+ var width = canvasData.width * (naturalWidth / canvasData.naturalWidth);
+ var height = canvasData.height * (naturalHeight / canvasData.naturalHeight);
+
+ canvasData.left -= (width - canvasData.width) / 2;
+ canvasData.top -= (height - canvasData.height) / 2;
+ canvasData.width = width;
+ canvasData.height = height;
+ canvasData.aspectRatio = naturalWidth / naturalHeight;
+ canvasData.naturalWidth = naturalWidth;
+ canvasData.naturalHeight = naturalHeight;
+ this.limitCanvas(true, false);
+ }
+
+ if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) {
+ canvasData.left = canvasData.oldLeft;
+ }
+
+ if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) {
+ canvasData.top = canvasData.oldTop;
+ }
+
+ canvasData.width = Math.min(Math.max(canvasData.width, canvasData.minWidth), canvasData.maxWidth);
+ canvasData.height = Math.min(Math.max(canvasData.height, canvasData.minHeight), canvasData.maxHeight);
+
+ this.limitCanvas(false, true);
+
+ canvasData.left = Math.min(Math.max(canvasData.left, canvasData.minLeft), canvasData.maxLeft);
+ canvasData.top = Math.min(Math.max(canvasData.top, canvasData.minTop), canvasData.maxTop);
+ canvasData.oldLeft = canvasData.left;
+ canvasData.oldTop = canvasData.top;
+
+ setStyle(this.canvas, extend({
+ width: canvasData.width,
+ height: canvasData.height
+ }, getTransforms({
+ translateX: canvasData.left,
+ translateY: canvasData.top
+ })));
+
+ this.renderImage(changed);
+
+ if (this.cropped && this.limited) {
+ this.limitCropBox(true, true);
+ }
+ },
+ renderImage: function renderImage(changed) {
+ var canvasData = this.canvasData,
+ imageData = this.imageData;
+
+ var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth);
+ var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight);
+
+ extend(imageData, {
+ width: width,
+ height: height,
+ left: (canvasData.width - width) / 2,
+ top: (canvasData.height - height) / 2
+ });
+ setStyle(this.image, extend({
+ width: imageData.width,
+ height: imageData.height
+ }, getTransforms(extend({
+ translateX: imageData.left,
+ translateY: imageData.top
+ }, imageData))));
+
+ if (changed) {
+ this.output();
+ }
+ },
+ initCropBox: function initCropBox() {
+ var options = this.options,
+ canvasData = this.canvasData;
+ var aspectRatio = options.aspectRatio;
+
+ var autoCropArea = Number(options.autoCropArea) || 0.8;
+ var cropBoxData = {
+ width: canvasData.width,
+ height: canvasData.height
+ };
+
+ if (aspectRatio) {
+ if (canvasData.height * aspectRatio > canvasData.width) {
+ cropBoxData.height = cropBoxData.width / aspectRatio;
+ } else {
+ cropBoxData.width = cropBoxData.height * aspectRatio;
+ }
+ }
+
+ this.cropBoxData = cropBoxData;
+ this.limitCropBox(true, true);
+
+ // Initialize auto crop area
+ cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);
+ cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight);
+
+ // The width/height of auto crop area must large than "minWidth/Height"
+ cropBoxData.width = Math.max(cropBoxData.minWidth, cropBoxData.width * autoCropArea);
+ cropBoxData.height = Math.max(cropBoxData.minHeight, cropBoxData.height * autoCropArea);
+ cropBoxData.left = canvasData.left + (canvasData.width - cropBoxData.width) / 2;
+ cropBoxData.top = canvasData.top + (canvasData.height - cropBoxData.height) / 2;
+ cropBoxData.oldLeft = cropBoxData.left;
+ cropBoxData.oldTop = cropBoxData.top;
+
+ this.initialCropBoxData = extend({}, cropBoxData);
+ },
+ limitCropBox: function limitCropBox(sizeLimited, positionLimited) {
+ var options = this.options,
+ containerData = this.containerData,
+ canvasData = this.canvasData,
+ cropBoxData = this.cropBoxData,
+ limited = this.limited;
+ var aspectRatio = options.aspectRatio;
+
+
+ if (sizeLimited) {
+ var minCropBoxWidth = Number(options.minCropBoxWidth) || 0;
+ var minCropBoxHeight = Number(options.minCropBoxHeight) || 0;
+ var maxCropBoxWidth = Math.min(containerData.width, limited ? canvasData.width : containerData.width);
+ var maxCropBoxHeight = Math.min(containerData.height, limited ? canvasData.height : containerData.height);
+
+ // The min/maxCropBoxWidth/Height must be less than container's width/height
+ minCropBoxWidth = Math.min(minCropBoxWidth, containerData.width);
+ minCropBoxHeight = Math.min(minCropBoxHeight, containerData.height);
+
+ if (aspectRatio) {
+ if (minCropBoxWidth && minCropBoxHeight) {
+ if (minCropBoxHeight * aspectRatio > minCropBoxWidth) {
+ minCropBoxHeight = minCropBoxWidth / aspectRatio;
+ } else {
+ minCropBoxWidth = minCropBoxHeight * aspectRatio;
+ }
+ } else if (minCropBoxWidth) {
+ minCropBoxHeight = minCropBoxWidth / aspectRatio;
+ } else if (minCropBoxHeight) {
+ minCropBoxWidth = minCropBoxHeight * aspectRatio;
+ }
+
+ if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) {
+ maxCropBoxHeight = maxCropBoxWidth / aspectRatio;
+ } else {
+ maxCropBoxWidth = maxCropBoxHeight * aspectRatio;
+ }
+ }
+
+ // The minWidth/Height must be less than maxWidth/Height
+ cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth);
+ cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight);
+ cropBoxData.maxWidth = maxCropBoxWidth;
+ cropBoxData.maxHeight = maxCropBoxHeight;
+ }
+
+ if (positionLimited) {
+ if (limited) {
+ cropBoxData.minLeft = Math.max(0, canvasData.left);
+ cropBoxData.minTop = Math.max(0, canvasData.top);
+ cropBoxData.maxLeft = Math.min(containerData.width, canvasData.left + canvasData.width) - cropBoxData.width;
+ cropBoxData.maxTop = Math.min(containerData.height, canvasData.top + canvasData.height) - cropBoxData.height;
+ } else {
+ cropBoxData.minLeft = 0;
+ cropBoxData.minTop = 0;
+ cropBoxData.maxLeft = containerData.width - cropBoxData.width;
+ cropBoxData.maxTop = containerData.height - cropBoxData.height;
+ }
+ }
+ },
+ renderCropBox: function renderCropBox() {
+ var options = this.options,
+ containerData = this.containerData,
+ cropBoxData = this.cropBoxData;
+
+
+ if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) {
+ cropBoxData.left = cropBoxData.oldLeft;
+ }
+
+ if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) {
+ cropBoxData.top = cropBoxData.oldTop;
+ }
+
+ cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);
+ cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight);
+
+ this.limitCropBox(false, true);
+
+ cropBoxData.left = Math.min(Math.max(cropBoxData.left, cropBoxData.minLeft), cropBoxData.maxLeft);
+ cropBoxData.top = Math.min(Math.max(cropBoxData.top, cropBoxData.minTop), cropBoxData.maxTop);
+ cropBoxData.oldLeft = cropBoxData.left;
+ cropBoxData.oldTop = cropBoxData.top;
+
+ if (options.movable && options.cropBoxMovable) {
+ // Turn to move the canvas when the crop box is equal to the container
+ setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL);
+ }
+
+ setStyle(this.cropBox, extend({
+ width: cropBoxData.width,
+ height: cropBoxData.height
+ }, getTransforms({
+ translateX: cropBoxData.left,
+ translateY: cropBoxData.top
+ })));
+
+ if (this.cropped && this.limited) {
+ this.limitCanvas(true, true);
+ }
+
+ if (!this.disabled) {
+ this.output();
+ }
+ },
+ output: function output() {
+ this.preview();
+
+ if (this.complete) {
+ dispatchEvent(this.element, EVENT_CROP, this.getData());
+ }
+ }
+};
+
+var preview = {
+ initPreview: function initPreview() {
+ var crossOrigin = this.crossOrigin;
+ var preview = this.options.preview;
+
+ var url = crossOrigin ? this.crossOriginUrl : this.url;
+ var image = document.createElement('img');
+
+ if (crossOrigin) {
+ image.crossOrigin = crossOrigin;
+ }
+
+ image.src = url;
+ this.viewBox.appendChild(image);
+ this.image2 = image;
+
+ if (!preview) {
+ return;
+ }
+
+ var previews = preview.querySelector ? [preview] : document.querySelectorAll(preview);
+
+ this.previews = previews;
+
+ each(previews, function (element) {
+ var img = document.createElement('img');
+
+ // Save the original size for recover
+ setData(element, DATA_PREVIEW, {
+ width: element.offsetWidth,
+ height: element.offsetHeight,
+ html: element.innerHTML
+ });
+
+ if (crossOrigin) {
+ img.crossOrigin = crossOrigin;
+ }
+
+ img.src = url;
+
+ /**
+ * Override img element styles
+ * Add `display:block` to avoid margin top issue
+ * Add `height:auto` to override `height` attribute on IE8
+ * (Occur only when margin-top <= -height)
+ */
+ img.style.cssText = 'display:block;' + 'width:100%;' + 'height:auto;' + 'min-width:0!important;' + 'min-height:0!important;' + 'max-width:none!important;' + 'max-height:none!important;' + 'image-orientation:0deg!important;"';
+
+ empty(element);
+ element.appendChild(img);
+ });
+ },
+ resetPreview: function resetPreview() {
+ each(this.previews, function (element) {
+ var data = getData(element, DATA_PREVIEW);
+
+ setStyle(element, {
+ width: data.width,
+ height: data.height
+ });
+
+ element.innerHTML = data.html;
+ removeData(element, DATA_PREVIEW);
+ });
+ },
+ preview: function preview() {
+ var imageData = this.imageData,
+ canvasData = this.canvasData,
+ cropBoxData = this.cropBoxData;
+ var cropBoxWidth = cropBoxData.width,
+ cropBoxHeight = cropBoxData.height;
+ var width = imageData.width,
+ height = imageData.height;
+
+ var left = cropBoxData.left - canvasData.left - imageData.left;
+ var top = cropBoxData.top - canvasData.top - imageData.top;
+
+ if (!this.cropped || this.disabled) {
+ return;
+ }
+
+ setStyle(this.image2, extend({
+ width: width,
+ height: height
+ }, getTransforms(extend({
+ translateX: -left,
+ translateY: -top
+ }, imageData))));
+
+ each(this.previews, function (element) {
+ var data = getData(element, DATA_PREVIEW);
+ var originalWidth = data.width;
+ var originalHeight = data.height;
+ var newWidth = originalWidth;
+ var newHeight = originalHeight;
+ var ratio = 1;
+
+ if (cropBoxWidth) {
+ ratio = originalWidth / cropBoxWidth;
+ newHeight = cropBoxHeight * ratio;
+ }
+
+ if (cropBoxHeight && newHeight > originalHeight) {
+ ratio = originalHeight / cropBoxHeight;
+ newWidth = cropBoxWidth * ratio;
+ newHeight = originalHeight;
+ }
+
+ setStyle(element, {
+ width: newWidth,
+ height: newHeight
+ });
+
+ setStyle(element.getElementsByTagName('img')[0], extend({
+ width: width * ratio,
+ height: height * ratio
+ }, getTransforms(extend({
+ translateX: -left * ratio,
+ translateY: -top * ratio
+ }, imageData))));
+ });
+ }
+};
+
+var events = {
+ bind: function bind() {
+ var element = this.element,
+ options = this.options,
+ cropper = this.cropper;
+
+
+ if (isFunction(options.cropstart)) {
+ addListener(element, EVENT_CROP_START, options.cropstart);
+ }
+
+ if (isFunction(options.cropmove)) {
+ addListener(element, EVENT_CROP_MOVE, options.cropmove);
+ }
+
+ if (isFunction(options.cropend)) {
+ addListener(element, EVENT_CROP_END, options.cropend);
+ }
+
+ if (isFunction(options.crop)) {
+ addListener(element, EVENT_CROP, options.crop);
+ }
+
+ if (isFunction(options.zoom)) {
+ addListener(element, EVENT_ZOOM, options.zoom);
+ }
+
+ addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = proxy(this.cropStart, this));
+
+ if (options.zoomable && options.zoomOnWheel) {
+ addListener(cropper, EVENT_WHEEL, this.onWheel = proxy(this.wheel, this));
+ }
+
+ if (options.toggleDragModeOnDblclick) {
+ addListener(cropper, EVENT_DBLCLICK, this.onDblclick = proxy(this.dblclick, this));
+ }
+
+ addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove = proxy(this.cropMove, this));
+ addListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd = proxy(this.cropEnd, this));
+
+ if (options.responsive) {
+ addListener(window, EVENT_RESIZE, this.onResize = proxy(this.resize, this));
+ }
+ },
+ unbind: function unbind() {
+ var element = this.element,
+ options = this.options,
+ cropper = this.cropper;
+
+
+ if (isFunction(options.cropstart)) {
+ removeListener(element, EVENT_CROP_START, options.cropstart);
+ }
+
+ if (isFunction(options.cropmove)) {
+ removeListener(element, EVENT_CROP_MOVE, options.cropmove);
+ }
+
+ if (isFunction(options.cropend)) {
+ removeListener(element, EVENT_CROP_END, options.cropend);
+ }
+
+ if (isFunction(options.crop)) {
+ removeListener(element, EVENT_CROP, options.crop);
+ }
+
+ if (isFunction(options.zoom)) {
+ removeListener(element, EVENT_ZOOM, options.zoom);
+ }
+
+ removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart);
+
+ if (options.zoomable && options.zoomOnWheel) {
+ removeListener(cropper, EVENT_WHEEL, this.onWheel);
+ }
+
+ if (options.toggleDragModeOnDblclick) {
+ removeListener(cropper, EVENT_DBLCLICK, this.onDblclick);
+ }
+
+ removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove);
+ removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd);
+
+ if (options.responsive) {
+ removeListener(window, EVENT_RESIZE, this.onResize);
+ }
+ }
+};
+
+var handlers = {
+ resize: function resize() {
+ var options = this.options,
+ container = this.container,
+ containerData = this.containerData;
+
+ var minContainerWidth = Number(options.minContainerWidth) || 200;
+ var minContainerHeight = Number(options.minContainerHeight) || 100;
+
+ if (this.disabled || containerData.width <= minContainerWidth || containerData.height <= minContainerHeight) {
+ return;
+ }
+
+ var ratio = container.offsetWidth / containerData.width;
+
+ // Resize when width changed or height changed
+ if (ratio !== 1 || container.offsetHeight !== containerData.height) {
+ var canvasData = void 0;
+ var cropBoxData = void 0;
+
+ if (options.restore) {
+ canvasData = this.getCanvasData();
+ cropBoxData = this.getCropBoxData();
+ }
+
+ this.render();
+
+ if (options.restore) {
+ this.setCanvasData(each(canvasData, function (n, i) {
+ canvasData[i] = n * ratio;
+ }));
+ this.setCropBoxData(each(cropBoxData, function (n, i) {
+ cropBoxData[i] = n * ratio;
+ }));
+ }
+ }
+ },
+ dblclick: function dblclick() {
+ if (this.disabled || this.options.dragMode === DRAG_MODE_NONE) {
+ return;
+ }
+
+ this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP);
+ },
+ wheel: function wheel(e) {
+ var _this = this;
+
+ var ratio = Number(this.options.wheelZoomRatio) || 0.1;
+ var delta = 1;
+
+ if (this.disabled) {
+ return;
+ }
+
+ e.preventDefault();
+
+ // Limit wheel speed to prevent zoom too fast (#21)
+ if (this.wheeling) {
+ return;
+ }
+
+ this.wheeling = true;
+
+ setTimeout(function () {
+ _this.wheeling = false;
+ }, 50);
+
+ if (e.deltaY) {
+ delta = e.deltaY > 0 ? 1 : -1;
+ } else if (e.wheelDelta) {
+ delta = -e.wheelDelta / 120;
+ } else if (e.detail) {
+ delta = e.detail > 0 ? 1 : -1;
+ }
+
+ this.zoom(-delta * ratio, e);
+ },
+ cropStart: function cropStart(e) {
+ if (this.disabled) {
+ return;
+ }
+
+ var options = this.options,
+ pointers = this.pointers;
+
+ var action = void 0;
+
+ if (e.changedTouches) {
+ // Handle touch event
+ each(e.changedTouches, function (touch) {
+ pointers[touch.identifier] = getPointer(touch);
+ });
+ } else {
+ // Handle mouse event and pointer event
+ pointers[e.pointerId || 0] = getPointer(e);
+ }
+
+ if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) {
+ action = ACTION_ZOOM;
+ } else {
+ action = getData(e.target, DATA_ACTION);
+ }
+
+ if (!REGEXP_ACTIONS.test(action)) {
+ return;
+ }
+
+ if (dispatchEvent(this.element, EVENT_CROP_START, {
+ originalEvent: e,
+ action: action
+ }) === false) {
+ return;
+ }
+
+ e.preventDefault();
+
+ this.action = action;
+ this.cropping = false;
+
+ if (action === ACTION_CROP) {
+ this.cropping = true;
+ addClass(this.dragBox, CLASS_MODAL);
+ }
+ },
+ cropMove: function cropMove(e) {
+ var action = this.action;
+
+
+ if (this.disabled || !action) {
+ return;
+ }
+
+ var pointers = this.pointers;
+
+
+ e.preventDefault();
+
+ if (dispatchEvent(this.element, EVENT_CROP_MOVE, {
+ originalEvent: e,
+ action: action
+ }) === false) {
+ return;
+ }
+
+ if (e.changedTouches) {
+ each(e.changedTouches, function (touch) {
+ extend(pointers[touch.identifier], getPointer(touch, true));
+ });
+ } else {
+ extend(pointers[e.pointerId || 0], getPointer(e, true));
+ }
+
+ this.change(e);
+ },
+ cropEnd: function cropEnd(e) {
+ if (this.disabled) {
+ return;
+ }
+
+ var action = this.action,
+ pointers = this.pointers;
+
+
+ if (e.changedTouches) {
+ each(e.changedTouches, function (touch) {
+ delete pointers[touch.identifier];
+ });
+ } else {
+ delete pointers[e.pointerId || 0];
+ }
+
+ if (!action) {
+ return;
+ }
+
+ e.preventDefault();
+
+ if (!Object.keys(pointers).length) {
+ this.action = '';
+ }
+
+ if (this.cropping) {
+ this.cropping = false;
+ toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal);
+ }
+
+ dispatchEvent(this.element, EVENT_CROP_END, {
+ originalEvent: e,
+ action: action
+ });
+ }
+};
+
+var change = {
+ change: function change(e) {
+ var options = this.options,
+ canvasData = this.canvasData,
+ containerData = this.containerData,
+ cropBoxData = this.cropBoxData,
+ pointers = this.pointers;
+ var action = this.action;
+ var aspectRatio = options.aspectRatio;
+ var left = cropBoxData.left,
+ top = cropBoxData.top,
+ width = cropBoxData.width,
+ height = cropBoxData.height;
+
+ var right = left + width;
+ var bottom = top + height;
+ var minLeft = 0;
+ var minTop = 0;
+ var maxWidth = containerData.width;
+ var maxHeight = containerData.height;
+ var renderable = true;
+ var offset = void 0;
+
+ // Locking aspect ratio in "free mode" by holding shift key
+ if (!aspectRatio && e.shiftKey) {
+ aspectRatio = width && height ? width / height : 1;
+ }
+
+ if (this.limited) {
+ minLeft = cropBoxData.minLeft;
+ minTop = cropBoxData.minTop;
+
+ maxWidth = minLeft + Math.min(containerData.width, canvasData.width, canvasData.left + canvasData.width);
+ maxHeight = minTop + Math.min(containerData.height, canvasData.height, canvasData.top + canvasData.height);
+ }
+
+ var pointer = pointers[Object.keys(pointers)[0]];
+ var range = {
+ x: pointer.endX - pointer.startX,
+ y: pointer.endY - pointer.startY
+ };
+ var check = function check(side) {
+ switch (side) {
+ case ACTION_EAST:
+ if (right + range.x > maxWidth) {
+ range.x = maxWidth - right;
+ }
+
+ break;
+
+ case ACTION_WEST:
+ if (left + range.x < minLeft) {
+ range.x = minLeft - left;
+ }
+
+ break;
+
+ case ACTION_NORTH:
+ if (top + range.y < minTop) {
+ range.y = minTop - top;
+ }
+
+ break;
+
+ case ACTION_SOUTH:
+ if (bottom + range.y > maxHeight) {
+ range.y = maxHeight - bottom;
+ }
+
+ break;
+
+ default:
+ }
+ };
+
+ switch (action) {
+ // Move crop box
+ case ACTION_ALL:
+ left += range.x;
+ top += range.y;
+ break;
+
+ // Resize crop box
+ case ACTION_EAST:
+ if (range.x >= 0 && (right >= maxWidth || aspectRatio && (top <= minTop || bottom >= maxHeight))) {
+ renderable = false;
+ break;
+ }
+
+ check(ACTION_EAST);
+ width += range.x;
+
+ if (aspectRatio) {
+ height = width / aspectRatio;
+ top -= range.x / aspectRatio / 2;
+ }
+
+ if (width < 0) {
+ action = ACTION_WEST;
+ width = 0;
+ }
+
+ break;
+
+ case ACTION_NORTH:
+ if (range.y <= 0 && (top <= minTop || aspectRatio && (left <= minLeft || right >= maxWidth))) {
+ renderable = false;
+ break;
+ }
+
+ check(ACTION_NORTH);
+ height -= range.y;
+ top += range.y;
+
+ if (aspectRatio) {
+ width = height * aspectRatio;
+ left += range.y * aspectRatio / 2;
+ }
+
+ if (height < 0) {
+ action = ACTION_SOUTH;
+ height = 0;
+ }
+
+ break;
+
+ case ACTION_WEST:
+ if (range.x <= 0 && (left <= minLeft || aspectRatio && (top <= minTop || bottom >= maxHeight))) {
+ renderable = false;
+ break;
+ }
+
+ check(ACTION_WEST);
+ width -= range.x;
+ left += range.x;
+
+ if (aspectRatio) {
+ height = width / aspectRatio;
+ top += range.x / aspectRatio / 2;
+ }
+
+ if (width < 0) {
+ action = ACTION_EAST;
+ width = 0;
+ }
+
+ break;
+
+ case ACTION_SOUTH:
+ if (range.y >= 0 && (bottom >= maxHeight || aspectRatio && (left <= minLeft || right >= maxWidth))) {
+ renderable = false;
+ break;
+ }
+
+ check(ACTION_SOUTH);
+ height += range.y;
+
+ if (aspectRatio) {
+ width = height * aspectRatio;
+ left -= range.y * aspectRatio / 2;
+ }
+
+ if (height < 0) {
+ action = ACTION_NORTH;
+ height = 0;
+ }
+
+ break;
+
+ case ACTION_NORTH_EAST:
+ if (aspectRatio) {
+ if (range.y <= 0 && (top <= minTop || right >= maxWidth)) {
+ renderable = false;
+ break;
+ }
+
+ check(ACTION_NORTH);
+ height -= range.y;
+ top += range.y;
+ width = height * aspectRatio;
+ } else {
+ check(ACTION_NORTH);
+ check(ACTION_EAST);
+
+ if (range.x >= 0) {
+ if (right < maxWidth) {
+ width += range.x;
+ } else if (range.y <= 0 && top <= minTop) {
+ renderable = false;
+ }
+ } else {
+ width += range.x;
+ }
+
+ if (range.y <= 0) {
+ if (top > minTop) {
+ height -= range.y;
+ top += range.y;
+ }
+ } else {
+ height -= range.y;
+ top += range.y;
+ }
+ }
+
+ if (width < 0 && height < 0) {
+ action = ACTION_SOUTH_WEST;
+ height = 0;
+ width = 0;
+ } else if (width < 0) {
+ action = ACTION_NORTH_WEST;
+ width = 0;
+ } else if (height < 0) {
+ action = ACTION_SOUTH_EAST;
+ height = 0;
+ }
+
+ break;
+
+ case ACTION_NORTH_WEST:
+ if (aspectRatio) {
+ if (range.y <= 0 && (top <= minTop || left <= minLeft)) {
+ renderable = false;
+ break;
+ }
+
+ check(ACTION_NORTH);
+ height -= range.y;
+ top += range.y;
+ width = height * aspectRatio;
+ left += range.y * aspectRatio;
+ } else {
+ check(ACTION_NORTH);
+ check(ACTION_WEST);
+
+ if (range.x <= 0) {
+ if (left > minLeft) {
+ width -= range.x;
+ left += range.x;
+ } else if (range.y <= 0 && top <= minTop) {
+ renderable = false;
+ }
+ } else {
+ width -= range.x;
+ left += range.x;
+ }
+
+ if (range.y <= 0) {
+ if (top > minTop) {
+ height -= range.y;
+ top += range.y;
+ }
+ } else {
+ height -= range.y;
+ top += range.y;
+ }
+ }
+
+ if (width < 0 && height < 0) {
+ action = ACTION_SOUTH_EAST;
+ height = 0;
+ width = 0;
+ } else if (width < 0) {
+ action = ACTION_NORTH_EAST;
+ width = 0;
+ } else if (height < 0) {
+ action = ACTION_SOUTH_WEST;
+ height = 0;
+ }
+
+ break;
+
+ case ACTION_SOUTH_WEST:
+ if (aspectRatio) {
+ if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) {
+ renderable = false;
+ break;
+ }
+
+ check(ACTION_WEST);
+ width -= range.x;
+ left += range.x;
+ height = width / aspectRatio;
+ } else {
+ check(ACTION_SOUTH);
+ check(ACTION_WEST);
+
+ if (range.x <= 0) {
+ if (left > minLeft) {
+ width -= range.x;
+ left += range.x;
+ } else if (range.y >= 0 && bottom >= maxHeight) {
+ renderable = false;
+ }
+ } else {
+ width -= range.x;
+ left += range.x;
+ }
+
+ if (range.y >= 0) {
+ if (bottom < maxHeight) {
+ height += range.y;
+ }
+ } else {
+ height += range.y;
+ }
+ }
+
+ if (width < 0 && height < 0) {
+ action = ACTION_NORTH_EAST;
+ height = 0;
+ width = 0;
+ } else if (width < 0) {
+ action = ACTION_SOUTH_EAST;
+ width = 0;
+ } else if (height < 0) {
+ action = ACTION_NORTH_WEST;
+ height = 0;
+ }
+
+ break;
+
+ case ACTION_SOUTH_EAST:
+ if (aspectRatio) {
+ if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) {
+ renderable = false;
+ break;
+ }
+
+ check(ACTION_EAST);
+ width += range.x;
+ height = width / aspectRatio;
+ } else {
+ check(ACTION_SOUTH);
+ check(ACTION_EAST);
+
+ if (range.x >= 0) {
+ if (right < maxWidth) {
+ width += range.x;
+ } else if (range.y >= 0 && bottom >= maxHeight) {
+ renderable = false;
+ }
+ } else {
+ width += range.x;
+ }
+
+ if (range.y >= 0) {
+ if (bottom < maxHeight) {
+ height += range.y;
+ }
+ } else {
+ height += range.y;
+ }
+ }
+
+ if (width < 0 && height < 0) {
+ action = ACTION_NORTH_WEST;
+ height = 0;
+ width = 0;
+ } else if (width < 0) {
+ action = ACTION_SOUTH_WEST;
+ width = 0;
+ } else if (height < 0) {
+ action = ACTION_NORTH_EAST;
+ height = 0;
+ }
+
+ break;
+
+ // Move canvas
+ case ACTION_MOVE:
+ this.move(range.x, range.y);
+ renderable = false;
+ break;
+
+ // Zoom canvas
+ case ACTION_ZOOM:
+ this.zoom(getMaxZoomRatio(pointers), e);
+ renderable = false;
+ break;
+
+ // Create crop box
+ case ACTION_CROP:
+ if (!range.x || !range.y) {
+ renderable = false;
+ break;
+ }
+
+ offset = getOffset(this.cropper);
+ left = pointer.startX - offset.left;
+ top = pointer.startY - offset.top;
+ width = cropBoxData.minWidth;
+ height = cropBoxData.minHeight;
+
+ if (range.x > 0) {
+ action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST;
+ } else if (range.x < 0) {
+ left -= width;
+ action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST;
+ }
+
+ if (range.y < 0) {
+ top -= height;
+ }
+
+ // Show the crop box if is hidden
+ if (!this.cropped) {
+ removeClass(this.cropBox, CLASS_HIDDEN);
+ this.cropped = true;
+
+ if (this.limited) {
+ this.limitCropBox(true, true);
+ }
+ }
+
+ break;
+
+ default:
+ }
+
+ if (renderable) {
+ cropBoxData.width = width;
+ cropBoxData.height = height;
+ cropBoxData.left = left;
+ cropBoxData.top = top;
+ this.action = action;
+ this.renderCropBox();
+ }
+
+ // Override
+ each(pointers, function (p) {
+ p.startX = p.endX;
+ p.startY = p.endY;
+ });
+ }
+};
+
+var methods = {
+ // Show the crop box manually
+ crop: function crop() {
+ if (this.ready && !this.disabled) {
+ if (!this.cropped) {
+ this.cropped = true;
+ this.limitCropBox(true, true);
+
+ if (this.options.modal) {
+ addClass(this.dragBox, CLASS_MODAL);
+ }
+
+ removeClass(this.cropBox, CLASS_HIDDEN);
+ }
+
+ this.setCropBoxData(this.initialCropBoxData);
+ }
+
+ return this;
+ },
+
+
+ // Reset the image and crop box to their initial states
+ reset: function reset() {
+ if (this.ready && !this.disabled) {
+ this.imageData = extend({}, this.initialImageData);
+ this.canvasData = extend({}, this.initialCanvasData);
+ this.cropBoxData = extend({}, this.initialCropBoxData);
+ this.renderCanvas();
+
+ if (this.cropped) {
+ this.renderCropBox();
+ }
+ }
+
+ return this;
+ },
+
+
+ // Clear the crop box
+ clear: function clear() {
+ if (this.cropped && !this.disabled) {
+ extend(this.cropBoxData, {
+ left: 0,
+ top: 0,
+ width: 0,
+ height: 0
+ });
+
+ this.cropped = false;
+ this.renderCropBox();
+ this.limitCanvas(true, true);
+
+ // Render canvas after crop box rendered
+ this.renderCanvas();
+ removeClass(this.dragBox, CLASS_MODAL);
+ addClass(this.cropBox, CLASS_HIDDEN);
+ }
+
+ return this;
+ },
+
+
+ /**
+ * Replace the image's src and rebuild the cropper
+ * @param {string} url - The new URL.
+ * @param {boolean} [onlyColorChanged] - Indicate if the new image only changed color.
+ * @returns {Object} this
+ */
+ replace: function replace(url) {
+ var onlyColorChanged = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
+
+ if (!this.disabled && url) {
+ if (this.isImg) {
+ this.element.src = url;
+ }
+
+ if (onlyColorChanged) {
+ this.url = url;
+ this.image.src = url;
+
+ if (this.ready) {
+ this.image2.src = url;
+
+ each(this.previews, function (element) {
+ element.getElementsByTagName('img')[0].src = url;
+ });
+ }
+ } else {
+ if (this.isImg) {
+ this.replaced = true;
+ }
+
+ // Clear previous data
+ this.options.data = null;
+ this.load(url);
+ }
+ }
+
+ return this;
+ },
+
+
+ // Enable (unfreeze) the cropper
+ enable: function enable() {
+ if (this.ready) {
+ this.disabled = false;
+ removeClass(this.cropper, CLASS_DISABLED);
+ }
+
+ return this;
+ },
+
+
+ // Disable (freeze) the cropper
+ disable: function disable() {
+ if (this.ready) {
+ this.disabled = true;
+ addClass(this.cropper, CLASS_DISABLED);
+ }
+
+ return this;
+ },
+
+
+ // Destroy the cropper and remove the instance from the image
+ destroy: function destroy() {
+ var element = this.element,
+ image = this.image;
+
+
+ if (this.loaded) {
+ if (this.isImg && this.replaced) {
+ element.src = this.originalUrl;
+ }
+
+ this.unbuild();
+ removeClass(element, CLASS_HIDDEN);
+ } else if (this.isImg) {
+ removeListener(element, EVENT_LOAD, this.onStart);
+ } else if (image) {
+ image.parentNode.removeChild(image);
+ }
+
+ removeData(element, NAMESPACE);
+
+ return this;
+ },
+
+
+ /**
+ * Move the canvas with relative offsets
+ * @param {number} offsetX - The relative offset distance on the x-axis.
+ * @param {number} offsetY - The relative offset distance on the y-axis.
+ * @returns {Object} this
+ */
+ move: function move(offsetX, offsetY) {
+ var _canvasData = this.canvasData,
+ left = _canvasData.left,
+ top = _canvasData.top;
+
+
+ return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY));
+ },
+
+
+ /**
+ * Move the canvas to an absolute point
+ * @param {number} x - The x-axis coordinate.
+ * @param {number} [y=x] - The y-axis coordinate.
+ * @returns {Object} this
+ */
+ moveTo: function moveTo(x) {
+ var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x;
+ var canvasData = this.canvasData;
+
+ var changed = false;
+
+ x = Number(x);
+ y = Number(y);
+
+ if (this.ready && !this.disabled && this.options.movable) {
+ if (isNumber(x)) {
+ canvasData.left = x;
+ changed = true;
+ }
+
+ if (isNumber(y)) {
+ canvasData.top = y;
+ changed = true;
+ }
+
+ if (changed) {
+ this.renderCanvas(true);
+ }
+ }
+
+ return this;
+ },
+
+
+ /**
+ * Zoom the canvas with a relative ratio
+ * @param {number} ratio - The target ratio.
+ * @param {Event} _originalEvent - The original event if any.
+ * @returns {Object} this
+ */
+ zoom: function zoom(ratio, _originalEvent) {
+ var canvasData = this.canvasData;
+
+
+ ratio = Number(ratio);
+
+ if (ratio < 0) {
+ ratio = 1 / (1 - ratio);
+ } else {
+ ratio = 1 + ratio;
+ }
+
+ return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent);
+ },
+
+
+ /**
+ * Zoom the canvas to an absolute ratio
+ * @param {number} ratio - The target ratio.
+ * @param {Object} pivot - The zoom pivot point coordinate.
+ * @param {Event} _originalEvent - The original event if any.
+ * @returns {Object} this
+ */
+ zoomTo: function zoomTo(ratio, pivot, _originalEvent) {
+ var options = this.options,
+ canvasData = this.canvasData;
+ var width = canvasData.width,
+ height = canvasData.height,
+ naturalWidth = canvasData.naturalWidth,
+ naturalHeight = canvasData.naturalHeight;
+
+
+ ratio = Number(ratio);
+
+ if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) {
+ var newWidth = naturalWidth * ratio;
+ var newHeight = naturalHeight * ratio;
+
+ if (dispatchEvent(this.element, EVENT_ZOOM, {
+ originalEvent: _originalEvent,
+ oldRatio: width / naturalWidth,
+ ratio: newWidth / naturalWidth
+ }) === false) {
+ return this;
+ }
+
+ if (_originalEvent) {
+ var pointers = this.pointers;
+
+ var offset = getOffset(this.cropper);
+ var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : {
+ pageX: _originalEvent.pageX,
+ pageY: _originalEvent.pageY
+ };
+
+ // Zoom from the triggering point of the event
+ canvasData.left -= (newWidth - width) * ((center.pageX - offset.left - canvasData.left) / width);
+ canvasData.top -= (newHeight - height) * ((center.pageY - offset.top - canvasData.top) / height);
+ } else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) {
+ canvasData.left -= (newWidth - width) * ((pivot.x - canvasData.left) / width);
+ canvasData.top -= (newHeight - height) * ((pivot.y - canvasData.top) / height);
+ } else {
+ // Zoom from the center of the canvas
+ canvasData.left -= (newWidth - width) / 2;
+ canvasData.top -= (newHeight - height) / 2;
+ }
+
+ canvasData.width = newWidth;
+ canvasData.height = newHeight;
+ this.renderCanvas(true);
+ }
+
+ return this;
+ },
+
+
+ /**
+ * Rotate the canvas with a relative degree
+ * @param {number} degree - The rotate degree.
+ * @returns {Object} this
+ */
+ rotate: function rotate(degree) {
+ return this.rotateTo((this.imageData.rotate || 0) + Number(degree));
+ },
+
+
+ /**
+ * Rotate the canvas to an absolute degree
+ * @param {number} degree - The rotate degree.
+ * @returns {Object} this
+ */
+ rotateTo: function rotateTo(degree) {
+ degree = Number(degree);
+
+ if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) {
+ this.imageData.rotate = degree % 360;
+ this.renderCanvas(true, true);
+ }
+
+ return this;
+ },
+
+
+ /**
+ * Scale the image on the x-axis.
+ * @param {number} scaleX - The scale ratio on the x-axis.
+ * @returns {Object} this
+ */
+ scaleX: function scaleX(_scaleX) {
+ var scaleY = this.imageData.scaleY;
+
+
+ return this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1);
+ },
+
+
+ /**
+ * Scale the image on the y-axis.
+ * @param {number} scaleY - The scale ratio on the y-axis.
+ * @returns {Object} this
+ */
+ scaleY: function scaleY(_scaleY) {
+ var scaleX = this.imageData.scaleX;
+
+
+ return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY);
+ },
+
+
+ /**
+ * Scale the image
+ * @param {number} scaleX - The scale ratio on the x-axis.
+ * @param {number} [scaleY=scaleX] - The scale ratio on the y-axis.
+ * @returns {Object} this
+ */
+ scale: function scale(scaleX) {
+ var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX;
+ var imageData = this.imageData;
+
+ var transformed = false;
+
+ scaleX = Number(scaleX);
+ scaleY = Number(scaleY);
+
+ if (this.ready && !this.disabled && this.options.scalable) {
+ if (isNumber(scaleX)) {
+ imageData.scaleX = scaleX;
+ transformed = true;
+ }
+
+ if (isNumber(scaleY)) {
+ imageData.scaleY = scaleY;
+ transformed = true;
+ }
+
+ if (transformed) {
+ this.renderCanvas(true, true);
+ }
+ }
+
+ return this;
+ },
+
+
+ /**
+ * Get the cropped area position and size data (base on the original image)
+ * @param {boolean} [rounded=false] - Indicate if round the data values or not.
+ * @returns {Object} The result cropped data.
+ */
+ getData: function getData$$1() {
+ var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
+ var options = this.options,
+ imageData = this.imageData,
+ canvasData = this.canvasData,
+ cropBoxData = this.cropBoxData;
+
+ var data = void 0;
+
+ if (this.ready && this.cropped) {
+ data = {
+ x: cropBoxData.left - canvasData.left,
+ y: cropBoxData.top - canvasData.top,
+ width: cropBoxData.width,
+ height: cropBoxData.height
+ };
+
+ var ratio = imageData.width / imageData.naturalWidth;
+
+ each(data, function (n, i) {
+ n /= ratio;
+ data[i] = rounded ? Math.round(n) : n;
+ });
+ } else {
+ data = {
+ x: 0,
+ y: 0,
+ width: 0,
+ height: 0
+ };
+ }
+
+ if (options.rotatable) {
+ data.rotate = imageData.rotate || 0;
+ }
+
+ if (options.scalable) {
+ data.scaleX = imageData.scaleX || 1;
+ data.scaleY = imageData.scaleY || 1;
+ }
+
+ return data;
+ },
+
+
+ /**
+ * Set the cropped area position and size with new data
+ * @param {Object} data - The new data.
+ * @returns {Object} this
+ */
+ setData: function setData$$1(data) {
+ var options = this.options,
+ imageData = this.imageData,
+ canvasData = this.canvasData;
+
+ var cropBoxData = {};
+
+ if (isFunction(data)) {
+ data = data.call(this.element);
+ }
+
+ if (this.ready && !this.disabled && isPlainObject(data)) {
+ var transformed = false;
+
+ if (options.rotatable) {
+ if (isNumber(data.rotate) && data.rotate !== imageData.rotate) {
+ imageData.rotate = data.rotate;
+ transformed = true;
+ }
+ }
+
+ if (options.scalable) {
+ if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) {
+ imageData.scaleX = data.scaleX;
+ transformed = true;
+ }
+
+ if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) {
+ imageData.scaleY = data.scaleY;
+ transformed = true;
+ }
+ }
+
+ if (transformed) {
+ this.renderCanvas(true, true);
+ }
+
+ var ratio = imageData.width / imageData.naturalWidth;
+
+ if (isNumber(data.x)) {
+ cropBoxData.left = data.x * ratio + canvasData.left;
+ }
+
+ if (isNumber(data.y)) {
+ cropBoxData.top = data.y * ratio + canvasData.top;
+ }
+
+ if (isNumber(data.width)) {
+ cropBoxData.width = data.width * ratio;
+ }
+
+ if (isNumber(data.height)) {
+ cropBoxData.height = data.height * ratio;
+ }
+
+ this.setCropBoxData(cropBoxData);
+ }
+
+ return this;
+ },
+
+
+ /**
+ * Get the container size data.
+ * @returns {Object} The result container data.
+ */
+ getContainerData: function getContainerData() {
+ return this.ready ? extend({}, this.containerData) : {};
+ },
+
+
+ /**
+ * Get the image position and size data.
+ * @returns {Object} The result image data.
+ */
+ getImageData: function getImageData() {
+ return this.loaded ? extend({}, this.imageData) : {};
+ },
+
+
+ /**
+ * Get the canvas position and size data.
+ * @returns {Object} The result canvas data.
+ */
+ getCanvasData: function getCanvasData() {
+ var canvasData = this.canvasData;
+
+ var data = {};
+
+ if (this.ready) {
+ each(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) {
+ data[n] = canvasData[n];
+ });
+ }
+
+ return data;
+ },
+
+
+ /**
+ * Set the canvas position and size with new data.
+ * @param {Object} data - The new canvas data.
+ * @returns {Object} this
+ */
+ setCanvasData: function setCanvasData(data) {
+ var canvasData = this.canvasData;
+ var aspectRatio = canvasData.aspectRatio;
+
+
+ if (isFunction(data)) {
+ data = data.call(this.element);
+ }
+
+ if (this.ready && !this.disabled && isPlainObject(data)) {
+ if (isNumber(data.left)) {
+ canvasData.left = data.left;
+ }
+
+ if (isNumber(data.top)) {
+ canvasData.top = data.top;
+ }
+
+ if (isNumber(data.width)) {
+ canvasData.width = data.width;
+ canvasData.height = data.width / aspectRatio;
+ } else if (isNumber(data.height)) {
+ canvasData.height = data.height;
+ canvasData.width = data.height * aspectRatio;
+ }
+
+ this.renderCanvas(true);
+ }
+
+ return this;
+ },
+
+
+ /**
+ * Get the crop box position and size data.
+ * @returns {Object} The result crop box data.
+ */
+ getCropBoxData: function getCropBoxData() {
+ var cropBoxData = this.cropBoxData;
+
+ var data = void 0;
+
+ if (this.ready && this.cropped) {
+ data = {
+ left: cropBoxData.left,
+ top: cropBoxData.top,
+ width: cropBoxData.width,
+ height: cropBoxData.height
+ };
+ }
+
+ return data || {};
+ },
+
+
+ /**
+ * Set the crop box position and size with new data.
+ * @param {Object} data - The new crop box data.
+ * @returns {Object} this
+ */
+ setCropBoxData: function setCropBoxData(data) {
+ var cropBoxData = this.cropBoxData;
+ var aspectRatio = this.options.aspectRatio;
+
+ var widthChanged = void 0;
+ var heightChanged = void 0;
+
+ if (isFunction(data)) {
+ data = data.call(this.element);
+ }
+
+ if (this.ready && this.cropped && !this.disabled && isPlainObject(data)) {
+ if (isNumber(data.left)) {
+ cropBoxData.left = data.left;
+ }
+
+ if (isNumber(data.top)) {
+ cropBoxData.top = data.top;
+ }
+
+ if (isNumber(data.width) && data.width !== cropBoxData.width) {
+ widthChanged = true;
+ cropBoxData.width = data.width;
+ }
+
+ if (isNumber(data.height) && data.height !== cropBoxData.height) {
+ heightChanged = true;
+ cropBoxData.height = data.height;
+ }
+
+ if (aspectRatio) {
+ if (widthChanged) {
+ cropBoxData.height = cropBoxData.width / aspectRatio;
+ } else if (heightChanged) {
+ cropBoxData.width = cropBoxData.height * aspectRatio;
+ }
+ }
+
+ this.renderCropBox();
+ }
+
+ return this;
+ },
+
+
+ /**
+ * Get a canvas drawn the cropped image.
+ * @param {Object} [options={}] - The config options.
+ * @returns {HTMLCanvasElement} - The result canvas.
+ */
+ getCroppedCanvas: function getCroppedCanvas() {
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+
+ if (!this.ready || !window.HTMLCanvasElement) {
+ return null;
+ }
+
+ var canvasData = this.canvasData;
+
+ var source = getSourceCanvas(this.image, this.imageData, canvasData, options);
+
+ // Returns the source canvas if it is not cropped.
+ if (!this.cropped) {
+ return source;
+ }
+
+ var _getData = this.getData(),
+ x = _getData.x,
+ y = _getData.y,
+ initialWidth = _getData.width,
+ initialHeight = _getData.height;
+
+ var aspectRatio = initialWidth / initialHeight;
+ var maxSizes = getContainSizes({
+ aspectRatio: aspectRatio,
+ width: options.maxWidth || Infinity,
+ height: options.maxHeight || Infinity
+ });
+ var minSizes = getContainSizes({
+ aspectRatio: aspectRatio,
+ width: options.minWidth || 0,
+ height: options.minHeight || 0
+ });
+
+ var _getContainSizes = getContainSizes({
+ aspectRatio: aspectRatio,
+ width: options.width || initialWidth,
+ height: options.height || initialHeight
+ }),
+ width = _getContainSizes.width,
+ height = _getContainSizes.height;
+
+ width = Math.min(maxSizes.width, Math.max(minSizes.width, width));
+ height = Math.min(maxSizes.height, Math.max(minSizes.height, height));
+
+ var canvas = document.createElement('canvas');
+ var context = canvas.getContext('2d');
+
+ canvas.width = normalizeDecimalNumber(width);
+ canvas.height = normalizeDecimalNumber(height);
+
+ context.fillStyle = options.fillColor || 'transparent';
+ context.fillRect(0, 0, width, height);
+
+ var _options$imageSmoothi = options.imageSmoothingEnabled,
+ imageSmoothingEnabled = _options$imageSmoothi === undefined ? true : _options$imageSmoothi,
+ imageSmoothingQuality = options.imageSmoothingQuality;
+
+
+ context.imageSmoothingEnabled = imageSmoothingEnabled;
+
+ if (imageSmoothingQuality) {
+ context.imageSmoothingQuality = imageSmoothingQuality;
+ }
+
+ // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage
+ var sourceWidth = source.width;
+ var sourceHeight = source.height;
+
+ // Source canvas parameters
+ var srcX = x;
+ var srcY = y;
+ var srcWidth = void 0;
+ var srcHeight = void 0;
+
+ // Destination canvas parameters
+ var dstX = void 0;
+ var dstY = void 0;
+ var dstWidth = void 0;
+ var dstHeight = void 0;
+
+ if (srcX <= -initialWidth || srcX > sourceWidth) {
+ srcX = 0;
+ srcWidth = 0;
+ dstX = 0;
+ dstWidth = 0;
+ } else if (srcX <= 0) {
+ dstX = -srcX;
+ srcX = 0;
+ srcWidth = Math.min(sourceWidth, initialWidth + srcX);
+ dstWidth = srcWidth;
+ } else if (srcX <= sourceWidth) {
+ dstX = 0;
+ srcWidth = Math.min(initialWidth, sourceWidth - srcX);
+ dstWidth = srcWidth;
+ }
+
+ if (srcWidth <= 0 || srcY <= -initialHeight || srcY > sourceHeight) {
+ srcY = 0;
+ srcHeight = 0;
+ dstY = 0;
+ dstHeight = 0;
+ } else if (srcY <= 0) {
+ dstY = -srcY;
+ srcY = 0;
+ srcHeight = Math.min(sourceHeight, initialHeight + srcY);
+ dstHeight = srcHeight;
+ } else if (srcY <= sourceHeight) {
+ dstY = 0;
+ srcHeight = Math.min(initialHeight, sourceHeight - srcY);
+ dstHeight = srcHeight;
+ }
+
+ // All the numerical parameters should be integer for `drawImage`
+ // https://github.com/fengyuanchen/cropper/issues/476
+ var params = [srcX, srcY, srcWidth, srcHeight];
+
+ // Avoid "IndexSizeError"
+ if (dstWidth > 0 && dstHeight > 0) {
+ var scale = width / initialWidth;
+
+ params.push(dstX * scale, dstY * scale, dstWidth * scale, dstHeight * scale);
+ }
+
+ context.drawImage.apply(context, [source].concat(toConsumableArray(params.map(function (param) {
+ return Math.floor(normalizeDecimalNumber(param));
+ }))));
+
+ return canvas;
+ },
+
+
+ /**
+ * Change the aspect ratio of the crop box.
+ * @param {number} aspectRatio - The new aspect ratio.
+ * @returns {Object} this
+ */
+ setAspectRatio: function setAspectRatio(aspectRatio) {
+ var options = this.options;
+
+
+ if (!this.disabled && !isUndefined(aspectRatio)) {
+ // 0 -> NaN
+ options.aspectRatio = Math.max(0, aspectRatio) || NaN;
+
+ if (this.ready) {
+ this.initCropBox();
+
+ if (this.cropped) {
+ this.renderCropBox();
+ }
+ }
+ }
+
+ return this;
+ },
+
+
+ /**
+ * Change the drag mode.
+ * @param {string} mode - The new drag mode.
+ * @returns {Object} this
+ */
+ setDragMode: function setDragMode(mode) {
+ var options = this.options,
+ dragBox = this.dragBox,
+ face = this.face;
+
+
+ if (this.loaded && !this.disabled) {
+ var croppable = mode === DRAG_MODE_CROP;
+ var movable = options.movable && mode === DRAG_MODE_MOVE;
+
+ mode = croppable || movable ? mode : DRAG_MODE_NONE;
+
+ setData(dragBox, DATA_ACTION, mode);
+ toggleClass(dragBox, CLASS_CROP, croppable);
+ toggleClass(dragBox, CLASS_MOVE, movable);
+
+ if (!options.cropBoxMovable) {
+ // Sync drag mode to crop box when it is not movable
+ setData(face, DATA_ACTION, mode);
+ toggleClass(face, CLASS_CROP, croppable);
+ toggleClass(face, CLASS_MOVE, movable);
+ }
+ }
+
+ return this;
+ }
+};
+
+var AnotherCropper = WINDOW.Cropper;
+
+var Cropper = function () {
+ /**
+ * Create a new Cropper.
+ * @param {Element} element - The target element for cropping.
+ * @param {Object} [options={}] - The configuration options.
+ */
+ function Cropper(element) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+ classCallCheck(this, Cropper);
+
+ if (!element || !REGEXP_TAG_NAME.test(element.tagName)) {
+ throw new Error('The first argument is required and must be an
or
element.');
+ }
+
+ this.element = element;
+ this.options = extend({}, DEFAULTS, isPlainObject(options) && options);
+ this.complete = false;
+ this.cropped = false;
+ this.disabled = false;
+ this.isImg = false;
+ this.limited = false;
+ this.loaded = false;
+ this.ready = false;
+ this.replaced = false;
+ this.wheeling = false;
+ this.originalUrl = '';
+ this.canvasData = null;
+ this.cropBoxData = null;
+ this.previews = null;
+ this.pointers = {};
+ this.init();
+ }
+
+ createClass(Cropper, [{
+ key: 'init',
+ value: function init() {
+ var element = this.element;
+
+ var tagName = element.tagName.toLowerCase();
+ var url = void 0;
+
+ if (getData(element, NAMESPACE)) {
+ return;
+ }
+
+ setData(element, NAMESPACE, this);
+
+ if (tagName === 'img') {
+ this.isImg = true;
+
+ // e.g.: "img/picture.jpg"
+ url = element.getAttribute('src') || '';
+ this.originalUrl = url;
+
+ // Stop when it's a blank image
+ if (!url) {
+ return;
+ }
+
+ // e.g.: "http://example.com/img/picture.jpg"
+ url = element.src;
+ } else if (tagName === 'canvas' && window.HTMLCanvasElement) {
+ url = element.toDataURL();
+ }
+
+ this.load(url);
+ }
+ }, {
+ key: 'load',
+ value: function load(url) {
+ var _this = this;
+
+ if (!url) {
+ return;
+ }
+
+ this.url = url;
+ this.imageData = {};
+
+ var element = this.element,
+ options = this.options;
+
+
+ if (!options.checkOrientation || !window.ArrayBuffer) {
+ this.clone();
+ return;
+ }
+
+ // XMLHttpRequest disallows to open a Data URL in some browsers like IE11 and Safari
+ if (REGEXP_DATA_URL.test(url)) {
+ if (REGEXP_DATA_URL_JPEG.test(url)) {
+ this.read(dataURLToArrayBuffer(url));
+ } else {
+ this.clone();
+ }
+
+ return;
+ }
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.onerror = function () {
+ _this.clone();
+ };
+
+ xhr.onload = function () {
+ _this.read(xhr.response);
+ };
+
+ if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) {
+ url = addTimestamp(url);
+ }
+
+ xhr.open('get', url);
+ xhr.responseType = 'arraybuffer';
+ xhr.withCredentials = element.crossOrigin === 'use-credentials';
+ xhr.send();
+ }
+ }, {
+ key: 'read',
+ value: function read(arrayBuffer) {
+ var options = this.options,
+ imageData = this.imageData;
+
+ var orientation = getOrientation(arrayBuffer);
+ var rotate = 0;
+ var scaleX = 1;
+ var scaleY = 1;
+
+ if (orientation > 1) {
+ this.url = arrayBufferToDataURL(arrayBuffer, 'image/jpeg');
+
+ var _parseOrientation = parseOrientation(orientation);
+
+ rotate = _parseOrientation.rotate;
+ scaleX = _parseOrientation.scaleX;
+ scaleY = _parseOrientation.scaleY;
+ }
+
+ if (options.rotatable) {
+ imageData.rotate = rotate;
+ }
+
+ if (options.scalable) {
+ imageData.scaleX = scaleX;
+ imageData.scaleY = scaleY;
+ }
+
+ this.clone();
+ }
+ }, {
+ key: 'clone',
+ value: function clone() {
+ var element = this.element,
+ url = this.url;
+
+ var crossOrigin = void 0;
+ var crossOriginUrl = void 0;
+
+ if (this.options.checkCrossOrigin && isCrossOriginURL(url)) {
+ crossOrigin = element.crossOrigin;
+
+
+ if (crossOrigin) {
+ crossOriginUrl = url;
+ } else {
+ crossOrigin = 'anonymous';
+
+ // Bust cache when there is not a "crossOrigin" property
+ crossOriginUrl = addTimestamp(url);
+ }
+ }
+
+ this.crossOrigin = crossOrigin;
+ this.crossOriginUrl = crossOriginUrl;
+
+ var image = document.createElement('img');
+
+ if (crossOrigin) {
+ image.crossOrigin = crossOrigin;
+ }
+
+ image.src = crossOriginUrl || url;
+
+ var start = proxy(this.start, this);
+ var stop = proxy(this.stop, this);
+
+ this.image = image;
+ this.onStart = start;
+ this.onStop = stop;
+
+ if (this.isImg) {
+ if (element.complete) {
+ this.start();
+ } else {
+ addListener(element, EVENT_LOAD, start);
+ }
+ } else {
+ addListener(image, EVENT_LOAD, start);
+ addListener(image, EVENT_ERROR, stop);
+ addClass(image, CLASS_HIDE);
+ element.parentNode.insertBefore(image, element.nextSibling);
+ }
+ }
+ }, {
+ key: 'start',
+ value: function start(event) {
+ var _this2 = this;
+
+ var image = this.isImg ? this.element : this.image;
+
+ if (event) {
+ removeListener(image, EVENT_LOAD, this.onStart);
+ removeListener(image, EVENT_ERROR, this.onStop);
+ }
+
+ getImageNaturalSizes(image, function (naturalWidth, naturalHeight) {
+ extend(_this2.imageData, {
+ naturalWidth: naturalWidth,
+ naturalHeight: naturalHeight,
+ aspectRatio: naturalWidth / naturalHeight
+ });
+ _this2.loaded = true;
+ _this2.build();
+ });
+ }
+ }, {
+ key: 'stop',
+ value: function stop() {
+ var image = this.image;
+
+
+ removeListener(image, EVENT_LOAD, this.onStart);
+ removeListener(image, EVENT_ERROR, this.onStop);
+ image.parentNode.removeChild(image);
+ this.image = null;
+ }
+ }, {
+ key: 'build',
+ value: function build() {
+ var _this3 = this;
+
+ if (!this.loaded) {
+ return;
+ }
+
+ // Unbuild first when replace
+ if (this.ready) {
+ this.unbuild();
+ }
+
+ var element = this.element,
+ options = this.options,
+ image = this.image;
+
+ // Create cropper elements
+
+ var container = element.parentNode;
+ var template = document.createElement('div');
+
+ template.innerHTML = TEMPLATE;
+
+ var cropper = template.querySelector('.' + NAMESPACE + '-container');
+ var canvas = cropper.querySelector('.' + NAMESPACE + '-canvas');
+ var dragBox = cropper.querySelector('.' + NAMESPACE + '-drag-box');
+ var cropBox = cropper.querySelector('.' + NAMESPACE + '-crop-box');
+ var face = cropBox.querySelector('.' + NAMESPACE + '-face');
+
+ this.container = container;
+ this.cropper = cropper;
+ this.canvas = canvas;
+ this.dragBox = dragBox;
+ this.cropBox = cropBox;
+ this.viewBox = cropper.querySelector('.' + NAMESPACE + '-view-box');
+ this.face = face;
+
+ canvas.appendChild(image);
+
+ // Hide the original image
+ addClass(element, CLASS_HIDDEN);
+
+ // Inserts the cropper after to the current image
+ container.insertBefore(cropper, element.nextSibling);
+
+ // Show the image if is hidden
+ if (!this.isImg) {
+ removeClass(image, CLASS_HIDE);
+ }
+
+ this.initPreview();
+ this.bind();
+
+ options.aspectRatio = Math.max(0, options.aspectRatio) || NaN;
+ options.viewMode = Math.max(0, Math.min(3, Math.round(options.viewMode))) || 0;
+
+ this.cropped = options.autoCrop;
+
+ if (options.autoCrop) {
+ if (options.modal) {
+ addClass(dragBox, CLASS_MODAL);
+ }
+ } else {
+ addClass(cropBox, CLASS_HIDDEN);
+ }
+
+ if (!options.guides) {
+ addClass(cropBox.getElementsByClassName(NAMESPACE + '-dashed'), CLASS_HIDDEN);
+ }
+
+ if (!options.center) {
+ addClass(cropBox.getElementsByClassName(NAMESPACE + '-center'), CLASS_HIDDEN);
+ }
+
+ if (options.background) {
+ addClass(cropper, NAMESPACE + '-bg');
+ }
+
+ if (!options.highlight) {
+ addClass(face, CLASS_INVISIBLE);
+ }
+
+ if (options.cropBoxMovable) {
+ addClass(face, CLASS_MOVE);
+ setData(face, DATA_ACTION, ACTION_ALL);
+ }
+
+ if (!options.cropBoxResizable) {
+ addClass(cropBox.getElementsByClassName(NAMESPACE + '-line'), CLASS_HIDDEN);
+ addClass(cropBox.getElementsByClassName(NAMESPACE + '-point'), CLASS_HIDDEN);
+ }
+
+ this.setDragMode(options.dragMode);
+ this.render();
+ this.ready = true;
+ this.setData(options.data);
+
+ // Call the "ready" option asynchronously to keep "image.cropper" is defined
+ this.completing = setTimeout(function () {
+ if (isFunction(options.ready)) {
+ addListener(element, EVENT_READY, options.ready, {
+ once: true
+ });
+ }
+
+ dispatchEvent(element, EVENT_READY);
+ dispatchEvent(element, EVENT_CROP, _this3.getData());
+
+ _this3.complete = true;
+ }, 0);
+ }
+ }, {
+ key: 'unbuild',
+ value: function unbuild() {
+ if (!this.ready) {
+ return;
+ }
+
+ if (!this.complete) {
+ clearTimeout(this.completing);
+ }
+
+ this.ready = false;
+ this.complete = false;
+ this.initialImageData = null;
+
+ // Clear `initialCanvasData` is necessary when replace
+ this.initialCanvasData = null;
+ this.initialCropBoxData = null;
+ this.containerData = null;
+ this.canvasData = null;
+
+ // Clear `cropBoxData` is necessary when replace
+ this.cropBoxData = null;
+ this.unbind();
+ this.resetPreview();
+ this.previews = null;
+ this.viewBox = null;
+ this.cropBox = null;
+ this.dragBox = null;
+ this.canvas = null;
+ this.container = null;
+ this.cropper.parentNode.removeChild(this.cropper);
+ this.cropper = null;
+ }
+
+ /**
+ * Get the no conflict cropper class.
+ * @returns {Cropper} The cropper class.
+ */
+
+ }], [{
+ key: 'noConflict',
+ value: function noConflict() {
+ window.Cropper = AnotherCropper;
+ return Cropper;
+ }
+
+ /**
+ * Change the default options.
+ * @param {Object} options - The new default options.
+ */
+
+ }, {
+ key: 'setDefaults',
+ value: function setDefaults(options) {
+ extend(DEFAULTS, isPlainObject(options) && options);
+ }
+ }]);
+ return Cropper;
+}();
+
+extend(Cropper.prototype, render, preview, events, handlers, change, methods);
+
+return Cropper;
+
+})));
diff --git a/library/cropperjs/docs/js/main.js b/library/cropperjs/docs/js/main.js
new file mode 100644
index 000000000..d74afbd60
--- /dev/null
+++ b/library/cropperjs/docs/js/main.js
@@ -0,0 +1,298 @@
+window.onload = function () {
+
+ 'use strict';
+
+ var Cropper = window.Cropper;
+ var URL = window.URL || window.webkitURL;
+ var container = document.querySelector('.img-container');
+ var image = container.getElementsByTagName('img').item(0);
+ var download = document.getElementById('download');
+ var actions = document.getElementById('actions');
+ var dataX = document.getElementById('dataX');
+ var dataY = document.getElementById('dataY');
+ var dataHeight = document.getElementById('dataHeight');
+ var dataWidth = document.getElementById('dataWidth');
+ var dataRotate = document.getElementById('dataRotate');
+ var dataScaleX = document.getElementById('dataScaleX');
+ var dataScaleY = document.getElementById('dataScaleY');
+ var options = {
+ aspectRatio: 16 / 9,
+ preview: '.img-preview',
+ ready: function (e) {
+ console.log(e.type);
+ },
+ cropstart: function (e) {
+ console.log(e.type, e.detail.action);
+ },
+ cropmove: function (e) {
+ console.log(e.type, e.detail.action);
+ },
+ cropend: function (e) {
+ console.log(e.type, e.detail.action);
+ },
+ crop: function (e) {
+ var data = e.detail;
+
+ console.log(e.type);
+ dataX.value = Math.round(data.x);
+ dataY.value = Math.round(data.y);
+ dataHeight.value = Math.round(data.height);
+ dataWidth.value = Math.round(data.width);
+ dataRotate.value = typeof data.rotate !== 'undefined' ? data.rotate : '';
+ dataScaleX.value = typeof data.scaleX !== 'undefined' ? data.scaleX : '';
+ dataScaleY.value = typeof data.scaleY !== 'undefined' ? data.scaleY : '';
+ },
+ zoom: function (e) {
+ console.log(e.type, e.detail.ratio);
+ }
+ };
+ var cropper = new Cropper(image, options);
+ var originalImageURL = image.src;
+ var uploadedImageType = 'image/jpeg';
+ var uploadedImageURL;
+
+ // Tooltip
+ $('[data-toggle="tooltip"]').tooltip();
+
+ // Buttons
+ if (!document.createElement('canvas').getContext) {
+ $('button[data-method="getCroppedCanvas"]').prop('disabled', true);
+ }
+
+ if (typeof document.createElement('cropper').style.transition === 'undefined') {
+ $('button[data-method="rotate"]').prop('disabled', true);
+ $('button[data-method="scale"]').prop('disabled', true);
+ }
+
+ // Download
+ if (typeof download.download === 'undefined') {
+ download.className += ' disabled';
+ }
+
+ // Options
+ actions.querySelector('.docs-toggles').onchange = function (event) {
+ var e = event || window.event;
+ var target = e.target || e.srcElement;
+ var cropBoxData;
+ var canvasData;
+ var isCheckbox;
+ var isRadio;
+
+ if (!cropper) {
+ return;
+ }
+
+ if (target.tagName.toLowerCase() === 'label') {
+ target = target.querySelector('input');
+ }
+
+ isCheckbox = target.type === 'checkbox';
+ isRadio = target.type === 'radio';
+
+ if (isCheckbox || isRadio) {
+ if (isCheckbox) {
+ options[target.name] = target.checked;
+ cropBoxData = cropper.getCropBoxData();
+ canvasData = cropper.getCanvasData();
+
+ options.ready = function () {
+ console.log('ready');
+ cropper.setCropBoxData(cropBoxData).setCanvasData(canvasData);
+ };
+ } else {
+ options[target.name] = target.value;
+ options.ready = function () {
+ console.log('ready');
+ };
+ }
+
+ // Restart
+ cropper.destroy();
+ cropper = new Cropper(image, options);
+ }
+ };
+
+ // Methods
+ actions.querySelector('.docs-buttons').onclick = function (event) {
+ var e = event || window.event;
+ var target = e.target || e.srcElement;
+ var cropped;
+ var result;
+ var input;
+ var data;
+
+ if (!cropper) {
+ return;
+ }
+
+ while (target !== this) {
+ if (target.getAttribute('data-method')) {
+ break;
+ }
+
+ target = target.parentNode;
+ }
+
+ if (target === this || target.disabled || target.className.indexOf('disabled') > -1) {
+ return;
+ }
+
+ data = {
+ method: target.getAttribute('data-method'),
+ target: target.getAttribute('data-target'),
+ option: target.getAttribute('data-option') || undefined,
+ secondOption: target.getAttribute('data-second-option') || undefined
+ };
+
+ cropped = cropper.cropped;
+
+ if (data.method) {
+ if (typeof data.target !== 'undefined') {
+ input = document.querySelector(data.target);
+
+ if (!target.hasAttribute('data-option') && data.target && input) {
+ try {
+ data.option = JSON.parse(input.value);
+ } catch (e) {
+ console.log(e.message);
+ }
+ }
+ }
+
+ switch (data.method) {
+ case 'rotate':
+ if (cropped && options.viewMode > 0) {
+ cropper.clear();
+ }
+
+ break;
+
+ case 'getCroppedCanvas':
+ try {
+ data.option = JSON.parse(data.option);
+ } catch (e) {
+ console.log(e.message);
+ }
+
+ if (uploadedImageType === 'image/jpeg') {
+ if (!data.option) {
+ data.option = {};
+ }
+
+ data.option.fillColor = '#fff';
+ }
+
+ break;
+ }
+
+ result = cropper[data.method](data.option, data.secondOption);
+
+ switch (data.method) {
+ case 'rotate':
+ if (cropped && options.viewMode > 0) {
+ cropper.crop();
+ }
+
+ break;
+
+ case 'scaleX':
+ case 'scaleY':
+ target.setAttribute('data-option', -data.option);
+ break;
+
+ case 'getCroppedCanvas':
+ if (result) {
+ // Bootstrap's Modal
+ $('#getCroppedCanvasModal').modal().find('.modal-body').html(result);
+
+ if (!download.disabled) {
+ download.href = result.toDataURL(uploadedImageType);
+ }
+ }
+
+ break;
+
+ case 'destroy':
+ cropper = null;
+
+ if (uploadedImageURL) {
+ URL.revokeObjectURL(uploadedImageURL);
+ uploadedImageURL = '';
+ image.src = originalImageURL;
+ }
+
+ break;
+ }
+
+ if (typeof result === 'object' && result !== cropper && input) {
+ try {
+ input.value = JSON.stringify(result);
+ } catch (e) {
+ console.log(e.message);
+ }
+ }
+ }
+ };
+
+ document.body.onkeydown = function (event) {
+ var e = event || window.event;
+
+ if (!cropper || this.scrollTop > 300) {
+ return;
+ }
+
+ switch (e.keyCode) {
+ case 37:
+ e.preventDefault();
+ cropper.move(-1, 0);
+ break;
+
+ case 38:
+ e.preventDefault();
+ cropper.move(0, -1);
+ break;
+
+ case 39:
+ e.preventDefault();
+ cropper.move(1, 0);
+ break;
+
+ case 40:
+ e.preventDefault();
+ cropper.move(0, 1);
+ break;
+ }
+ };
+
+ // Import image
+ var inputImage = document.getElementById('inputImage');
+
+ if (URL) {
+ inputImage.onchange = function () {
+ var files = this.files;
+ var file;
+
+ if (cropper && files && files.length) {
+ file = files[0];
+
+ if (/^image\/\w+/.test(file.type)) {
+ uploadedImageType = file.type;
+
+ if (uploadedImageURL) {
+ URL.revokeObjectURL(uploadedImageURL);
+ }
+
+ image.src = uploadedImageURL = URL.createObjectURL(file);
+ cropper.destroy();
+ cropper = new Cropper(image, options);
+ inputImage.value = null;
+ } else {
+ window.alert('Please choose an image file.');
+ }
+ }
+ };
+ } else {
+ inputImage.disabled = true;
+ inputImage.parentNode.className += ' disabled';
+ }
+};
diff --git a/library/cropperjs/examples/a-range-of-aspect-ratio.html b/library/cropperjs/examples/a-range-of-aspect-ratio.html
new file mode 100644
index 000000000..fae5cb60b
--- /dev/null
+++ b/library/cropperjs/examples/a-range-of-aspect-ratio.html
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+ Cropper.js
+
+
+
+
+
+
+
Cropper with a range of aspect ratio
+
+
+
+
+
+
+
+
+
diff --git a/library/cropperjs/examples/crop-a-round-image.html b/library/cropperjs/examples/crop-a-round-image.html
new file mode 100644
index 000000000..da027d847
--- /dev/null
+++ b/library/cropperjs/examples/crop-a-round-image.html
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+ Cropper.js
+
+
+
+
+
+
+
Crop a round image
+
Image
+
+
+
+
Result
+
+ Crop
+
+
+
+
+
+
+
+
diff --git a/library/cropperjs/examples/crop-cross-origin-image.html b/library/cropperjs/examples/crop-cross-origin-image.html
new file mode 100644
index 000000000..54f08664a
--- /dev/null
+++ b/library/cropperjs/examples/crop-cross-origin-image.html
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+ Cropper.js
+
+
+
+
+
+
+
Crop a cross origin image
+
A cross origin image with a crossorigin
attribute and an available Access-Control-Allow-Origin
response header can be cropped by Cropper.
+
Image
+
+
+
+
Result
+
+
+
+
+
+
+
diff --git a/library/cropperjs/examples/crop-on-canvas.html b/library/cropperjs/examples/crop-on-canvas.html
new file mode 100644
index 000000000..228e36f75
--- /dev/null
+++ b/library/cropperjs/examples/crop-on-canvas.html
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+ Cropper.js
+
+
+
+
+
+
+
Crop on canvas with Cropper
+
Image
+
+
+
+
Canvas
+
+
+
+
+
+
+
+
+
diff --git a/library/cropperjs/examples/cropper-in-modal.html b/library/cropperjs/examples/cropper-in-modal.html
new file mode 100644
index 000000000..a9ce3e80b
--- /dev/null
+++ b/library/cropperjs/examples/cropper-in-modal.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Cropper.js
+
+
+
+
+
+
+
+
Cropper in a Bootstrap modal
+
+
+
+ Launch the demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/library/cropperjs/examples/customize-preview.html b/library/cropperjs/examples/customize-preview.html
new file mode 100644
index 000000000..ea1c24b88
--- /dev/null
+++ b/library/cropperjs/examples/customize-preview.html
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+ Cropper.js
+
+
+
+
+
+
+
Customize preview for Cropper
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/library/cropperjs/examples/fixed-crop-box.html b/library/cropperjs/examples/fixed-crop-box.html
new file mode 100644
index 000000000..b9f1101fb
--- /dev/null
+++ b/library/cropperjs/examples/fixed-crop-box.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+ Cropper.js
+
+
+
+
+
+
+
Cropper with fixed crop box
+
+
+
+
+
+
+
+
+
diff --git a/library/cropperjs/examples/full-crop-box.html b/library/cropperjs/examples/full-crop-box.html
new file mode 100644
index 000000000..7065eab94
--- /dev/null
+++ b/library/cropperjs/examples/full-crop-box.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+ Cropper.js
+
+
+
+
+
+
+
Cropper with full crop box
+
+
+
+
+
+
+
+
+
diff --git a/library/cropperjs/examples/mask-an-image.html b/library/cropperjs/examples/mask-an-image.html
new file mode 100644
index 000000000..d821da43b
--- /dev/null
+++ b/library/cropperjs/examples/mask-an-image.html
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+ Cropper.js
+
+
+
+
+
+
+
+
Mask an image (Redaction)
+
Image
+
+
+
+
Result
+
Mask
+
+
+
+
+
+
+
+
diff --git a/library/cropperjs/examples/multiple-croppers.html b/library/cropperjs/examples/multiple-croppers.html
new file mode 100644
index 000000000..6b12e70b2
--- /dev/null
+++ b/library/cropperjs/examples/multiple-croppers.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+ Cropper.js
+
+
+
+
+
+
+
Multiple Croppers
+
Cropper
+
+
+
+
Another
+
+
+
+
+
+
+
+
+
diff --git a/library/cropperjs/examples/responsive-container.html b/library/cropperjs/examples/responsive-container.html
new file mode 100644
index 000000000..c1aa7483b
--- /dev/null
+++ b/library/cropperjs/examples/responsive-container.html
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+ Cropper.js
+
+
+
+
+
+
+
Cropper with responsive container
+
+ Replace Image
+
+
+
+
+
+
+
+
+
+
diff --git a/library/cropperjs/package-lock.json b/library/cropperjs/package-lock.json
new file mode 100644
index 000000000..229ee70fa
--- /dev/null
+++ b/library/cropperjs/package-lock.json
@@ -0,0 +1,9111 @@
+{
+ "name": "cropperjs",
+ "version": "1.2.2",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "JSONStream": {
+ "version": "0.8.4",
+ "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-0.8.4.tgz",
+ "integrity": "sha1-kWV9/m/4V0gwZhMrRhi2Lo9Ih70=",
+ "dev": true,
+ "requires": {
+ "jsonparse": "0.0.5",
+ "through": "2.3.8"
+ }
+ },
+ "acorn": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz",
+ "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==",
+ "dev": true
+ },
+ "acorn-jsx": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
+ "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
+ "dev": true,
+ "requires": {
+ "acorn": "3.3.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+ "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
+ "dev": true
+ }
+ }
+ },
+ "ajv": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.3.tgz",
+ "integrity": "sha1-wG9Zh3jETGsWGrr+NGa4GtGBTtI=",
+ "dev": true,
+ "requires": {
+ "co": "4.6.0",
+ "fast-deep-equal": "1.0.0",
+ "json-schema-traverse": "0.3.1",
+ "json-stable-stringify": "1.0.1"
+ }
+ },
+ "ajv-keywords": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.0.tgz",
+ "integrity": "sha1-opbhf3v658HOT34N5T0pyzIWLfA=",
+ "dev": true
+ },
+ "alphanum-sort": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
+ "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
+ "dev": true
+ },
+ "amdefine": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+ "dev": true
+ },
+ "ansi-align": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
+ "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=",
+ "dev": true,
+ "requires": {
+ "string-width": "2.1.1"
+ }
+ },
+ "ansi-escapes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz",
+ "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "anymatch": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
+ "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
+ "dev": true,
+ "requires": {
+ "micromatch": "2.3.11",
+ "normalize-path": "2.1.1"
+ }
+ },
+ "argparse": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
+ "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "1.0.3"
+ }
+ },
+ "arr-diff": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "1.1.0"
+ }
+ },
+ "arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+ "dev": true
+ },
+ "array-differ": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
+ "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=",
+ "dev": true
+ },
+ "array-filter": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz",
+ "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=",
+ "dev": true
+ },
+ "array-find-index": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
+ "dev": true
+ },
+ "array-map": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz",
+ "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=",
+ "dev": true
+ },
+ "array-reduce": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz",
+ "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=",
+ "dev": true
+ },
+ "array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "dev": true,
+ "requires": {
+ "array-uniq": "1.0.3"
+ }
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+ "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+ "dev": true
+ },
+ "arrify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+ "dev": true
+ },
+ "asn1": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+ "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
+ "dev": true
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ },
+ "async-each": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
+ "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
+ "dev": true
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true
+ },
+ "autoprefixer": {
+ "version": "6.7.7",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz",
+ "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=",
+ "dev": true,
+ "requires": {
+ "browserslist": "1.7.7",
+ "caniuse-db": "1.0.30000744",
+ "normalize-range": "0.1.2",
+ "num2fraction": "1.2.2",
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ },
+ "dependencies": {
+ "browserslist": {
+ "version": "1.7.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
+ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
+ "dev": true,
+ "requires": {
+ "caniuse-db": "1.0.30000744",
+ "electron-to-chromium": "1.3.24"
+ }
+ }
+ }
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+ "dev": true
+ },
+ "aws4": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+ "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
+ "dev": true
+ },
+ "babel-code-frame": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "esutils": "2.0.2",
+ "js-tokens": "3.0.2"
+ }
+ },
+ "babel-core": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz",
+ "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "6.26.0",
+ "babel-generator": "6.26.0",
+ "babel-helpers": "6.24.1",
+ "babel-messages": "6.23.0",
+ "babel-register": "6.26.0",
+ "babel-runtime": "6.26.0",
+ "babel-template": "6.26.0",
+ "babel-traverse": "6.26.0",
+ "babel-types": "6.26.0",
+ "babylon": "6.18.0",
+ "convert-source-map": "1.5.0",
+ "debug": "2.6.9",
+ "json5": "0.5.1",
+ "lodash": "4.17.4",
+ "minimatch": "3.0.4",
+ "path-is-absolute": "1.0.1",
+ "private": "0.1.7",
+ "slash": "1.0.0",
+ "source-map": "0.5.7"
+ }
+ },
+ "babel-generator": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz",
+ "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=",
+ "dev": true,
+ "requires": {
+ "babel-messages": "6.23.0",
+ "babel-runtime": "6.26.0",
+ "babel-types": "6.26.0",
+ "detect-indent": "4.0.0",
+ "jsesc": "1.3.0",
+ "lodash": "4.17.4",
+ "source-map": "0.5.7",
+ "trim-right": "1.0.1"
+ }
+ },
+ "babel-helper-builder-binary-assignment-operator-visitor": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
+ "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=",
+ "dev": true,
+ "requires": {
+ "babel-helper-explode-assignable-expression": "6.24.1",
+ "babel-runtime": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-helper-call-delegate": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz",
+ "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=",
+ "dev": true,
+ "requires": {
+ "babel-helper-hoist-variables": "6.24.1",
+ "babel-runtime": "6.26.0",
+ "babel-traverse": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-helper-define-map": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz",
+ "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=",
+ "dev": true,
+ "requires": {
+ "babel-helper-function-name": "6.24.1",
+ "babel-runtime": "6.26.0",
+ "babel-types": "6.26.0",
+ "lodash": "4.17.4"
+ }
+ },
+ "babel-helper-explode-assignable-expression": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz",
+ "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "babel-traverse": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-helper-function-name": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
+ "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
+ "dev": true,
+ "requires": {
+ "babel-helper-get-function-arity": "6.24.1",
+ "babel-runtime": "6.26.0",
+ "babel-template": "6.26.0",
+ "babel-traverse": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-helper-get-function-arity": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
+ "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-helper-hoist-variables": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz",
+ "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-helper-optimise-call-expression": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz",
+ "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-helper-regex": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz",
+ "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "babel-types": "6.26.0",
+ "lodash": "4.17.4"
+ }
+ },
+ "babel-helper-remap-async-to-generator": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
+ "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
+ "dev": true,
+ "requires": {
+ "babel-helper-function-name": "6.24.1",
+ "babel-runtime": "6.26.0",
+ "babel-template": "6.26.0",
+ "babel-traverse": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-helper-replace-supers": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
+ "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=",
+ "dev": true,
+ "requires": {
+ "babel-helper-optimise-call-expression": "6.24.1",
+ "babel-messages": "6.23.0",
+ "babel-runtime": "6.26.0",
+ "babel-template": "6.26.0",
+ "babel-traverse": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-helpers": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
+ "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "babel-template": "6.26.0"
+ }
+ },
+ "babel-messages": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0"
+ }
+ },
+ "babel-plugin-check-es2015-constants": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
+ "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0"
+ }
+ },
+ "babel-plugin-external-helpers": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-external-helpers/-/babel-plugin-external-helpers-6.22.0.tgz",
+ "integrity": "sha1-IoX0iwK9Xe3oUXXK+MYuhq3M76E=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0"
+ }
+ },
+ "babel-plugin-syntax-async-functions": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
+ "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
+ "dev": true
+ },
+ "babel-plugin-syntax-exponentiation-operator": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
+ "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
+ "dev": true
+ },
+ "babel-plugin-syntax-trailing-function-commas": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
+ "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
+ "dev": true
+ },
+ "babel-plugin-transform-async-to-generator": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
+ "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
+ "dev": true,
+ "requires": {
+ "babel-helper-remap-async-to-generator": "6.24.1",
+ "babel-plugin-syntax-async-functions": "6.13.0",
+ "babel-runtime": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-arrow-functions": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
+ "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-block-scoped-functions": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
+ "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-block-scoping": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz",
+ "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "babel-template": "6.26.0",
+ "babel-traverse": "6.26.0",
+ "babel-types": "6.26.0",
+ "lodash": "4.17.4"
+ }
+ },
+ "babel-plugin-transform-es2015-classes": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz",
+ "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=",
+ "dev": true,
+ "requires": {
+ "babel-helper-define-map": "6.26.0",
+ "babel-helper-function-name": "6.24.1",
+ "babel-helper-optimise-call-expression": "6.24.1",
+ "babel-helper-replace-supers": "6.24.1",
+ "babel-messages": "6.23.0",
+ "babel-runtime": "6.26.0",
+ "babel-template": "6.26.0",
+ "babel-traverse": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-computed-properties": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz",
+ "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "babel-template": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-destructuring": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
+ "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-duplicate-keys": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
+ "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-for-of": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
+ "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-function-name": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz",
+ "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=",
+ "dev": true,
+ "requires": {
+ "babel-helper-function-name": "6.24.1",
+ "babel-runtime": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-literals": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
+ "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-modules-amd": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz",
+ "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
+ "babel-runtime": "6.26.0",
+ "babel-template": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-modules-commonjs": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz",
+ "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-transform-strict-mode": "6.24.1",
+ "babel-runtime": "6.26.0",
+ "babel-template": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-modules-systemjs": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz",
+ "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=",
+ "dev": true,
+ "requires": {
+ "babel-helper-hoist-variables": "6.24.1",
+ "babel-runtime": "6.26.0",
+ "babel-template": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-modules-umd": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz",
+ "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-transform-es2015-modules-amd": "6.24.1",
+ "babel-runtime": "6.26.0",
+ "babel-template": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-object-super": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz",
+ "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=",
+ "dev": true,
+ "requires": {
+ "babel-helper-replace-supers": "6.24.1",
+ "babel-runtime": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-parameters": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz",
+ "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=",
+ "dev": true,
+ "requires": {
+ "babel-helper-call-delegate": "6.24.1",
+ "babel-helper-get-function-arity": "6.24.1",
+ "babel-runtime": "6.26.0",
+ "babel-template": "6.26.0",
+ "babel-traverse": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-shorthand-properties": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz",
+ "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-spread": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
+ "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-sticky-regex": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz",
+ "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=",
+ "dev": true,
+ "requires": {
+ "babel-helper-regex": "6.26.0",
+ "babel-runtime": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-template-literals": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
+ "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-typeof-symbol": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
+ "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-unicode-regex": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
+ "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=",
+ "dev": true,
+ "requires": {
+ "babel-helper-regex": "6.26.0",
+ "babel-runtime": "6.26.0",
+ "regexpu-core": "2.0.0"
+ }
+ },
+ "babel-plugin-transform-exponentiation-operator": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz",
+ "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=",
+ "dev": true,
+ "requires": {
+ "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1",
+ "babel-plugin-syntax-exponentiation-operator": "6.13.0",
+ "babel-runtime": "6.26.0"
+ }
+ },
+ "babel-plugin-transform-regenerator": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
+ "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=",
+ "dev": true,
+ "requires": {
+ "regenerator-transform": "0.10.1"
+ }
+ },
+ "babel-plugin-transform-strict-mode": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
+ "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "babel-types": "6.26.0"
+ }
+ },
+ "babel-preset-env": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz",
+ "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==",
+ "dev": true,
+ "requires": {
+ "babel-plugin-check-es2015-constants": "6.22.0",
+ "babel-plugin-syntax-trailing-function-commas": "6.22.0",
+ "babel-plugin-transform-async-to-generator": "6.24.1",
+ "babel-plugin-transform-es2015-arrow-functions": "6.22.0",
+ "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0",
+ "babel-plugin-transform-es2015-block-scoping": "6.26.0",
+ "babel-plugin-transform-es2015-classes": "6.24.1",
+ "babel-plugin-transform-es2015-computed-properties": "6.24.1",
+ "babel-plugin-transform-es2015-destructuring": "6.23.0",
+ "babel-plugin-transform-es2015-duplicate-keys": "6.24.1",
+ "babel-plugin-transform-es2015-for-of": "6.23.0",
+ "babel-plugin-transform-es2015-function-name": "6.24.1",
+ "babel-plugin-transform-es2015-literals": "6.22.0",
+ "babel-plugin-transform-es2015-modules-amd": "6.24.1",
+ "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
+ "babel-plugin-transform-es2015-modules-systemjs": "6.24.1",
+ "babel-plugin-transform-es2015-modules-umd": "6.24.1",
+ "babel-plugin-transform-es2015-object-super": "6.24.1",
+ "babel-plugin-transform-es2015-parameters": "6.24.1",
+ "babel-plugin-transform-es2015-shorthand-properties": "6.24.1",
+ "babel-plugin-transform-es2015-spread": "6.22.0",
+ "babel-plugin-transform-es2015-sticky-regex": "6.24.1",
+ "babel-plugin-transform-es2015-template-literals": "6.22.0",
+ "babel-plugin-transform-es2015-typeof-symbol": "6.23.0",
+ "babel-plugin-transform-es2015-unicode-regex": "6.24.1",
+ "babel-plugin-transform-exponentiation-operator": "6.24.1",
+ "babel-plugin-transform-regenerator": "6.26.0",
+ "browserslist": "2.5.0",
+ "invariant": "2.2.2",
+ "semver": "5.4.1"
+ }
+ },
+ "babel-register": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
+ "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
+ "dev": true,
+ "requires": {
+ "babel-core": "6.26.0",
+ "babel-runtime": "6.26.0",
+ "core-js": "2.5.1",
+ "home-or-tmp": "2.0.0",
+ "lodash": "4.17.4",
+ "mkdirp": "0.5.1",
+ "source-map-support": "0.4.18"
+ }
+ },
+ "babel-runtime": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+ "dev": true,
+ "requires": {
+ "core-js": "2.5.1",
+ "regenerator-runtime": "0.11.0"
+ }
+ },
+ "babel-template": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+ "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "babel-traverse": "6.26.0",
+ "babel-types": "6.26.0",
+ "babylon": "6.18.0",
+ "lodash": "4.17.4"
+ }
+ },
+ "babel-traverse": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+ "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "6.26.0",
+ "babel-messages": "6.23.0",
+ "babel-runtime": "6.26.0",
+ "babel-types": "6.26.0",
+ "babylon": "6.18.0",
+ "debug": "2.6.9",
+ "globals": "9.18.0",
+ "invariant": "2.2.2",
+ "lodash": "4.17.4"
+ }
+ },
+ "babel-types": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+ "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "esutils": "2.0.2",
+ "lodash": "4.17.4",
+ "to-fast-properties": "1.0.3"
+ }
+ },
+ "babylon": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+ "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+ "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "tweetnacl": "0.14.5"
+ }
+ },
+ "binary-extensions": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz",
+ "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=",
+ "dev": true
+ },
+ "bluebird": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
+ "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
+ "dev": true
+ },
+ "boom": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
+ "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
+ "dev": true,
+ "requires": {
+ "hoek": "4.2.0"
+ }
+ },
+ "boxen": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.2.2.tgz",
+ "integrity": "sha1-Px1AMsMP/qnUsCwyLq8up0HcvOU=",
+ "dev": true,
+ "requires": {
+ "ansi-align": "2.0.0",
+ "camelcase": "4.1.0",
+ "chalk": "2.3.0",
+ "cli-boxes": "1.0.0",
+ "string-width": "2.1.1",
+ "term-size": "1.2.0",
+ "widest-line": "1.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+ "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.5.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+ "dev": true,
+ "requires": {
+ "balanced-match": "1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "1.8.5",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+ "dev": true,
+ "requires": {
+ "expand-range": "1.8.2",
+ "preserve": "0.2.0",
+ "repeat-element": "1.1.2"
+ }
+ },
+ "browserslist": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.5.0.tgz",
+ "integrity": "sha512-6Vw1LIigGw8zCK0gxczksUMZlO+oPUwBazAztMmFL/F8D5wB0qCuxRJGYgYM3JzaO0v2ZMRIg+nnnOgNsPGHeA==",
+ "dev": true,
+ "requires": {
+ "caniuse-lite": "1.0.30000744",
+ "electron-to-chromium": "1.3.24"
+ }
+ },
+ "builtin-modules": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+ "dev": true
+ },
+ "caller-path": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
+ "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
+ "dev": true,
+ "requires": {
+ "callsites": "0.2.0"
+ }
+ },
+ "callsites": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
+ "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+ "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
+ "dev": true
+ },
+ "camelcase-keys": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+ "dev": true,
+ "requires": {
+ "camelcase": "2.1.1",
+ "map-obj": "1.0.1"
+ }
+ },
+ "caniuse-api": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz",
+ "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=",
+ "dev": true,
+ "requires": {
+ "browserslist": "1.7.7",
+ "caniuse-db": "1.0.30000744",
+ "lodash.memoize": "4.1.2",
+ "lodash.uniq": "4.5.0"
+ },
+ "dependencies": {
+ "browserslist": {
+ "version": "1.7.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
+ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
+ "dev": true,
+ "requires": {
+ "caniuse-db": "1.0.30000744",
+ "electron-to-chromium": "1.3.24"
+ }
+ }
+ }
+ },
+ "caniuse-db": {
+ "version": "1.0.30000744",
+ "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000744.tgz",
+ "integrity": "sha1-AHWP991fcTjTShVgjcz3Glllb/4=",
+ "dev": true
+ },
+ "caniuse-lite": {
+ "version": "1.0.30000744",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000744.tgz",
+ "integrity": "sha1-hg+lyDujT+YZOX1gfzC7R0ghZxs=",
+ "dev": true
+ },
+ "capture-stack-trace": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz",
+ "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=",
+ "dev": true
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "2.2.1",
+ "escape-string-regexp": "1.0.5",
+ "has-ansi": "2.0.0",
+ "strip-ansi": "3.0.1",
+ "supports-color": "2.0.0"
+ }
+ },
+ "chardet": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
+ "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
+ "dev": true
+ },
+ "chokidar": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
+ "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
+ "dev": true,
+ "requires": {
+ "anymatch": "1.3.2",
+ "async-each": "1.0.1",
+ "glob-parent": "2.0.0",
+ "inherits": "2.0.3",
+ "is-binary-path": "1.0.1",
+ "is-glob": "2.0.1",
+ "path-is-absolute": "1.0.1",
+ "readdirp": "2.1.0"
+ }
+ },
+ "circular-json": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
+ "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
+ "dev": true
+ },
+ "clap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz",
+ "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3"
+ }
+ },
+ "cli-boxes": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
+ "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=",
+ "dev": true
+ },
+ "cli-cursor": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "2.0.0"
+ }
+ },
+ "cli-spinners": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.1.0.tgz",
+ "integrity": "sha1-8YR7FohE2RemceudFH499JfJDQY=",
+ "dev": true
+ },
+ "cli-width": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+ "dev": true
+ },
+ "cliui": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+ "dev": true,
+ "requires": {
+ "string-width": "1.0.2",
+ "strip-ansi": "3.0.1",
+ "wrap-ansi": "2.1.0"
+ },
+ "dependencies": {
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "1.1.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "strip-ansi": "3.0.1"
+ }
+ }
+ }
+ },
+ "clone": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz",
+ "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=",
+ "dev": true
+ },
+ "clone-regexp": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-1.0.0.tgz",
+ "integrity": "sha1-6uCiQT9VwJQvgYwin+/OhF1/Oxw=",
+ "dev": true,
+ "requires": {
+ "is-regexp": "1.0.0",
+ "is-supported-regexp-flag": "1.0.0"
+ }
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+ "dev": true
+ },
+ "coa": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz",
+ "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=",
+ "dev": true,
+ "requires": {
+ "q": "1.5.0"
+ }
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+ "dev": true
+ },
+ "color": {
+ "version": "0.11.4",
+ "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz",
+ "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=",
+ "dev": true,
+ "requires": {
+ "clone": "1.0.2",
+ "color-convert": "1.9.0",
+ "color-string": "0.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
+ "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-diff": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/color-diff/-/color-diff-0.1.7.tgz",
+ "integrity": "sha1-bbeM2UgqjkWdQIIer0tQMoPcuOI=",
+ "dev": true
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "color-string": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz",
+ "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "colorguard": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/colorguard/-/colorguard-1.2.0.tgz",
+ "integrity": "sha1-8/rK9cquuk71RlPZ+yW7cxd8DYQ=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "color-diff": "0.1.7",
+ "log-symbols": "1.0.2",
+ "object-assign": "4.1.1",
+ "pipetteur": "2.0.3",
+ "plur": "2.1.2",
+ "postcss": "5.2.18",
+ "postcss-reporter": "1.4.1",
+ "text-table": "0.2.0",
+ "yargs": "1.3.3"
+ },
+ "dependencies": {
+ "postcss-reporter": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-1.4.1.tgz",
+ "integrity": "sha1-wTbwpbFhkV83ndN2XGEHX357mvI=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "lodash": "4.17.4",
+ "log-symbols": "1.0.2",
+ "postcss": "5.2.18"
+ }
+ },
+ "yargs": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-1.3.3.tgz",
+ "integrity": "sha1-BU3oth8i7v23IHBZ6u+da4P7kxo=",
+ "dev": true
+ }
+ }
+ },
+ "colormin": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz",
+ "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=",
+ "dev": true,
+ "requires": {
+ "color": "0.11.4",
+ "css-color-names": "0.0.4",
+ "has": "1.0.1"
+ }
+ },
+ "colors": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
+ "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+ "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "1.0.0"
+ }
+ },
+ "commander": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
+ "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "concat-stream": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
+ "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "readable-stream": "2.3.3",
+ "typedarray": "0.0.6"
+ }
+ },
+ "configstore": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.1.tgz",
+ "integrity": "sha512-5oNkD/L++l0O6xGXxb1EWS7SivtjfGQlRyxJsYgE0Z495/L81e2h4/d3r969hoPXuFItzNOKMtsXgYG4c7dYvw==",
+ "dev": true,
+ "requires": {
+ "dot-prop": "4.2.0",
+ "graceful-fs": "4.1.11",
+ "make-dir": "1.1.0",
+ "unique-string": "1.0.0",
+ "write-file-atomic": "2.3.0",
+ "xdg-basedir": "3.0.0"
+ }
+ },
+ "contains-path": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz",
+ "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=",
+ "dev": true
+ },
+ "convert-source-map": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz",
+ "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=",
+ "dev": true
+ },
+ "core-js": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz",
+ "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=",
+ "dev": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+ "dev": true
+ },
+ "cosmiconfig": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz",
+ "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==",
+ "dev": true,
+ "requires": {
+ "is-directory": "0.3.1",
+ "js-yaml": "3.7.0",
+ "minimist": "1.2.0",
+ "object-assign": "4.1.1",
+ "os-homedir": "1.0.2",
+ "parse-json": "2.2.0",
+ "require-from-string": "1.2.1"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ }
+ }
+ },
+ "cp-file": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-3.2.0.tgz",
+ "integrity": "sha1-b4NhYlRiTwrViqSqjQdvAmvn4Yg=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "mkdirp": "0.5.1",
+ "nested-error-stacks": "1.0.2",
+ "object-assign": "4.1.1",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1",
+ "readable-stream": "2.3.3"
+ }
+ },
+ "cpy": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/cpy/-/cpy-4.0.1.tgz",
+ "integrity": "sha1-tnJn66LzlgugalphrJQDNCKDNCQ=",
+ "dev": true,
+ "requires": {
+ "cp-file": "3.2.0",
+ "globby": "4.1.0",
+ "meow": "3.7.0",
+ "nested-error-stacks": "1.0.2",
+ "object-assign": "4.1.1",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "cpy-cli": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cpy-cli/-/cpy-cli-1.0.1.tgz",
+ "integrity": "sha1-Z/taSi3sKMqKv/N13kuecfanVhw=",
+ "dev": true,
+ "requires": {
+ "cpy": "4.0.1",
+ "meow": "3.7.0"
+ }
+ },
+ "create-error-class": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
+ "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
+ "dev": true,
+ "requires": {
+ "capture-stack-trace": "1.0.0"
+ }
+ },
+ "cross-spawn": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "4.1.1",
+ "shebang-command": "1.2.0",
+ "which": "1.3.0"
+ }
+ },
+ "cryptiles": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
+ "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
+ "dev": true,
+ "requires": {
+ "boom": "5.2.0"
+ },
+ "dependencies": {
+ "boom": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
+ "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
+ "dev": true,
+ "requires": {
+ "hoek": "4.2.0"
+ }
+ }
+ }
+ },
+ "crypto-random-string": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
+ "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=",
+ "dev": true
+ },
+ "css-color-function": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/css-color-function/-/css-color-function-1.3.3.tgz",
+ "integrity": "sha1-jtJMLAIFBzM5+voAS8jBQfzLKC4=",
+ "dev": true,
+ "requires": {
+ "balanced-match": "0.1.0",
+ "color": "0.11.4",
+ "debug": "3.1.0",
+ "rgb": "0.1.0"
+ },
+ "dependencies": {
+ "balanced-match": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.1.0.tgz",
+ "integrity": "sha1-tQS9BYabOSWd0MXvw12EMXbczEo=",
+ "dev": true
+ },
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "css-color-list": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/css-color-list/-/css-color-list-0.0.1.tgz",
+ "integrity": "sha1-hxjoaVrnosyHh76HFfHACKfyixU=",
+ "dev": true,
+ "requires": {
+ "css-color-names": "0.0.1"
+ },
+ "dependencies": {
+ "css-color-names": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.1.tgz",
+ "integrity": "sha1-XQVI+iVkVu3kqaDCrHqxnT6xrYE=",
+ "dev": true
+ }
+ }
+ },
+ "css-color-names": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
+ "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
+ "dev": true
+ },
+ "css-rule-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/css-rule-stream/-/css-rule-stream-1.1.0.tgz",
+ "integrity": "sha1-N4bnGYmD2WWibjGVfgkHjLt3BaI=",
+ "dev": true,
+ "requires": {
+ "css-tokenize": "1.0.1",
+ "duplexer2": "0.0.2",
+ "ldjson-stream": "1.2.1",
+ "through2": "0.6.5"
+ }
+ },
+ "css-tokenize": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/css-tokenize/-/css-tokenize-1.0.1.tgz",
+ "integrity": "sha1-RiXLHtohwUOFi3+B1oA8HSb8FL4=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "readable-stream": "1.1.14"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "0.0.1",
+ "string_decoder": "0.10.31"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
+ }
+ }
+ },
+ "css-unit-converter": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz",
+ "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=",
+ "dev": true
+ },
+ "cssnano": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz",
+ "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=",
+ "dev": true,
+ "requires": {
+ "autoprefixer": "6.7.7",
+ "decamelize": "1.2.0",
+ "defined": "1.0.0",
+ "has": "1.0.1",
+ "object-assign": "4.1.1",
+ "postcss": "5.2.18",
+ "postcss-calc": "5.3.1",
+ "postcss-colormin": "2.2.2",
+ "postcss-convert-values": "2.6.1",
+ "postcss-discard-comments": "2.0.4",
+ "postcss-discard-duplicates": "2.1.0",
+ "postcss-discard-empty": "2.1.0",
+ "postcss-discard-overridden": "0.1.1",
+ "postcss-discard-unused": "2.2.3",
+ "postcss-filter-plugins": "2.0.2",
+ "postcss-merge-idents": "2.1.7",
+ "postcss-merge-longhand": "2.0.2",
+ "postcss-merge-rules": "2.1.2",
+ "postcss-minify-font-values": "1.0.5",
+ "postcss-minify-gradients": "1.0.5",
+ "postcss-minify-params": "1.2.2",
+ "postcss-minify-selectors": "2.1.1",
+ "postcss-normalize-charset": "1.1.1",
+ "postcss-normalize-url": "3.0.8",
+ "postcss-ordered-values": "2.2.3",
+ "postcss-reduce-idents": "2.4.0",
+ "postcss-reduce-initial": "1.0.1",
+ "postcss-reduce-transforms": "1.0.4",
+ "postcss-svgo": "2.1.6",
+ "postcss-unique-selectors": "2.0.2",
+ "postcss-value-parser": "3.3.0",
+ "postcss-zindex": "2.2.0"
+ }
+ },
+ "csso": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz",
+ "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=",
+ "dev": true,
+ "requires": {
+ "clap": "1.2.3",
+ "source-map": "0.5.7"
+ }
+ },
+ "cuint": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz",
+ "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=",
+ "dev": true
+ },
+ "currently-unhandled": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+ "dev": true,
+ "requires": {
+ "array-find-index": "1.0.2"
+ }
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0"
+ }
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
+ },
+ "deep-extend": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz",
+ "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=",
+ "dev": true
+ },
+ "deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+ "dev": true
+ },
+ "define-properties": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
+ "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
+ "dev": true,
+ "requires": {
+ "foreach": "2.0.5",
+ "object-keys": "1.0.11"
+ }
+ },
+ "defined": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
+ "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
+ "dev": true
+ },
+ "del": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
+ "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
+ "dev": true,
+ "requires": {
+ "globby": "5.0.0",
+ "is-path-cwd": "1.0.0",
+ "is-path-in-cwd": "1.0.0",
+ "object-assign": "4.1.1",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1",
+ "rimraf": "2.6.2"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "globby": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
+ "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
+ "dev": true,
+ "requires": {
+ "array-union": "1.0.2",
+ "arrify": "1.0.1",
+ "glob": "7.1.2",
+ "object-assign": "4.1.1",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1"
+ }
+ }
+ }
+ },
+ "del-cli": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/del-cli/-/del-cli-1.1.0.tgz",
+ "integrity": "sha1-J1V9aaC335ncuqHjSgnmrGWR0sQ=",
+ "dev": true,
+ "requires": {
+ "del": "3.0.0",
+ "meow": "3.7.0",
+ "update-notifier": "2.3.0"
+ },
+ "dependencies": {
+ "del": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz",
+ "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=",
+ "dev": true,
+ "requires": {
+ "globby": "6.1.0",
+ "is-path-cwd": "1.0.0",
+ "is-path-in-cwd": "1.0.0",
+ "p-map": "1.2.0",
+ "pify": "3.0.0",
+ "rimraf": "2.6.2"
+ }
+ },
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "globby": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+ "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
+ "dev": true,
+ "requires": {
+ "array-union": "1.0.2",
+ "glob": "7.1.2",
+ "object-assign": "4.1.1",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ }
+ }
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true
+ },
+ "dependency-graph": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.5.1.tgz",
+ "integrity": "sha512-nk3OjiI68T3876/tsm4Hm57ye7zc4Kl87hkcALBMCuSrN1q1NvuY5HCnSSkoJjGdrMo5gmu0WTN2cV/D76q/mw==",
+ "dev": true
+ },
+ "detect-indent": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
+ "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
+ "dev": true,
+ "requires": {
+ "repeating": "2.0.1"
+ }
+ },
+ "diff": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz",
+ "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==",
+ "dev": true
+ },
+ "doctrine": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz",
+ "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==",
+ "dev": true,
+ "requires": {
+ "esutils": "2.0.2"
+ }
+ },
+ "doiuse": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/doiuse/-/doiuse-2.6.0.tgz",
+ "integrity": "sha1-GJLRC2Gpo1at2/K2FJM+gfi7ODQ=",
+ "dev": true,
+ "requires": {
+ "browserslist": "1.7.7",
+ "caniuse-db": "1.0.30000744",
+ "css-rule-stream": "1.1.0",
+ "duplexer2": "0.0.2",
+ "jsonfilter": "1.1.2",
+ "ldjson-stream": "1.2.1",
+ "lodash": "4.17.4",
+ "multimatch": "2.1.0",
+ "postcss": "5.2.18",
+ "source-map": "0.4.4",
+ "through2": "0.6.5",
+ "yargs": "3.32.0"
+ },
+ "dependencies": {
+ "browserslist": {
+ "version": "1.7.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
+ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
+ "dev": true,
+ "requires": {
+ "caniuse-db": "1.0.30000744",
+ "electron-to-chromium": "1.3.24"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "os-locale": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+ "dev": true,
+ "requires": {
+ "lcid": "1.0.0"
+ }
+ },
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "dev": true,
+ "requires": {
+ "amdefine": "1.0.1"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "1.1.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "strip-ansi": "3.0.1"
+ }
+ },
+ "yargs": {
+ "version": "3.32.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
+ "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=",
+ "dev": true,
+ "requires": {
+ "camelcase": "2.1.1",
+ "cliui": "3.2.0",
+ "decamelize": "1.2.0",
+ "os-locale": "1.4.0",
+ "string-width": "1.0.2",
+ "window-size": "0.1.4",
+ "y18n": "3.2.1"
+ }
+ }
+ }
+ },
+ "dot-prop": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
+ "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==",
+ "dev": true,
+ "requires": {
+ "is-obj": "1.0.1"
+ }
+ },
+ "duplexer": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+ "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
+ "dev": true
+ },
+ "duplexer2": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz",
+ "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "1.1.14"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "0.0.1",
+ "string_decoder": "0.10.31"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
+ }
+ }
+ },
+ "duplexer3": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+ "dev": true
+ },
+ "ecc-jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+ "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "jsbn": "0.1.1"
+ }
+ },
+ "editorconfig": {
+ "version": "0.13.3",
+ "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.13.3.tgz",
+ "integrity": "sha512-WkjsUNVCu+ITKDj73QDvi0trvpdDWdkDyHybDGSXPfekLCqwmpD7CP7iPbvBgosNuLcI96XTDwNa75JyFl7tEQ==",
+ "dev": true,
+ "requires": {
+ "bluebird": "3.5.1",
+ "commander": "2.11.0",
+ "lru-cache": "3.2.0",
+ "semver": "5.4.1",
+ "sigmund": "1.0.1"
+ },
+ "dependencies": {
+ "lru-cache": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz",
+ "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=",
+ "dev": true,
+ "requires": {
+ "pseudomap": "1.0.2"
+ }
+ }
+ }
+ },
+ "electron-to-chromium": {
+ "version": "1.3.24",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.24.tgz",
+ "integrity": "sha1-m3uIuwXOufoBahd4M8wt3jiPIbY=",
+ "dev": true
+ },
+ "error-ex": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
+ "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "0.2.1"
+ }
+ },
+ "es-abstract": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.9.0.tgz",
+ "integrity": "sha512-kk3IJoKo7A3pWJc0OV8yZ/VEX2oSUytfekrJiqoxBlKJMFAJVJVpGdHClCCTdv+Fn2zHfpDHHIelMFhZVfef3Q==",
+ "dev": true,
+ "requires": {
+ "es-to-primitive": "1.1.1",
+ "function-bind": "1.1.1",
+ "has": "1.0.1",
+ "is-callable": "1.1.3",
+ "is-regex": "1.0.4"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz",
+ "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=",
+ "dev": true,
+ "requires": {
+ "is-callable": "1.1.3",
+ "is-date-object": "1.0.1",
+ "is-symbol": "1.0.1"
+ }
+ },
+ "es6-promise": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.1.1.tgz",
+ "integrity": "sha512-OaU1hHjgJf+b0NzsxCg7NdIYERD6Hy/PEmFLTjw+b65scuisG3Kt4QoTvJ66BBkPZ581gr0kpoVzKnxniM8nng==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "eslint": {
+ "version": "4.14.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.14.0.tgz",
+ "integrity": "sha512-Ul6CSGRjKscEyg0X/EeNs7o2XdnbTEOD1OM8cTjmx85RPcBJQrEhZLevhuJZNAE/vS2iVl5Uhgiqf3h5uLMCJQ==",
+ "dev": true,
+ "requires": {
+ "ajv": "5.5.2",
+ "babel-code-frame": "6.26.0",
+ "chalk": "2.3.0",
+ "concat-stream": "1.6.0",
+ "cross-spawn": "5.1.0",
+ "debug": "3.1.0",
+ "doctrine": "2.0.2",
+ "eslint-scope": "3.7.1",
+ "eslint-visitor-keys": "1.0.0",
+ "espree": "3.5.2",
+ "esquery": "1.0.0",
+ "esutils": "2.0.2",
+ "file-entry-cache": "2.0.0",
+ "functional-red-black-tree": "1.0.1",
+ "glob": "7.1.2",
+ "globals": "11.1.0",
+ "ignore": "3.3.5",
+ "imurmurhash": "0.1.4",
+ "inquirer": "3.3.0",
+ "is-resolvable": "1.0.1",
+ "js-yaml": "3.10.0",
+ "json-stable-stringify-without-jsonify": "1.0.1",
+ "levn": "0.3.0",
+ "lodash": "4.17.4",
+ "minimatch": "3.0.4",
+ "mkdirp": "0.5.1",
+ "natural-compare": "1.4.0",
+ "optionator": "0.8.2",
+ "path-is-inside": "1.0.2",
+ "pluralize": "7.0.0",
+ "progress": "2.0.0",
+ "require-uncached": "1.0.3",
+ "semver": "5.4.1",
+ "strip-ansi": "4.0.0",
+ "strip-json-comments": "2.0.1",
+ "table": "4.0.2",
+ "text-table": "0.2.0"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+ "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+ "dev": true,
+ "requires": {
+ "co": "4.6.0",
+ "fast-deep-equal": "1.0.0",
+ "fast-json-stable-stringify": "2.0.0",
+ "json-schema-traverse": "0.3.1"
+ }
+ },
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+ "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.5.0"
+ }
+ },
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "esprima": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
+ "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "globals": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.1.0.tgz",
+ "integrity": "sha512-uEuWt9mqTlPDwSqi+sHjD4nWU/1N+q0fiWI9T1mZpD2UENqX20CFD5T/ziLZvztPaBKl7ZylUi1q6Qfm7E2CiQ==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz",
+ "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==",
+ "dev": true,
+ "requires": {
+ "argparse": "1.0.9",
+ "esprima": "4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "3.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "eslint-config-airbnb-base": {
+ "version": "12.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz",
+ "integrity": "sha512-/vjm0Px5ZCpmJqnjIzcFb9TKZrKWz0gnuG/7Gfkt0Db1ELJR51xkZth+t14rYdqWgX836XbuxtArbIHlVhbLBA==",
+ "dev": true,
+ "requires": {
+ "eslint-restricted-globals": "0.1.1"
+ }
+ },
+ "eslint-import-resolver-node": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz",
+ "integrity": "sha512-yUtXS15gIcij68NmXmP9Ni77AQuCN0itXbCc/jWd8C6/yKZaSNXicpC8cgvjnxVdmfsosIXrjpzFq7GcDryb6A==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "resolve": "1.4.0"
+ }
+ },
+ "eslint-module-utils": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz",
+ "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "pkg-dir": "1.0.0"
+ }
+ },
+ "eslint-plugin-import": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz",
+ "integrity": "sha512-Rf7dfKJxZ16QuTgVv1OYNxkZcsu/hULFnC+e+w0Gzi6jMC3guQoWQgxYxc54IDRinlb6/0v5z/PxxIKmVctN+g==",
+ "dev": true,
+ "requires": {
+ "builtin-modules": "1.1.1",
+ "contains-path": "0.1.0",
+ "debug": "2.6.9",
+ "doctrine": "1.5.0",
+ "eslint-import-resolver-node": "0.3.1",
+ "eslint-module-utils": "2.1.1",
+ "has": "1.0.1",
+ "lodash.cond": "4.5.2",
+ "minimatch": "3.0.4",
+ "read-pkg-up": "2.0.0"
+ },
+ "dependencies": {
+ "doctrine": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+ "dev": true,
+ "requires": {
+ "esutils": "2.0.2",
+ "isarray": "1.0.0"
+ }
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "requires": {
+ "locate-path": "2.0.0"
+ }
+ },
+ "load-json-file": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+ "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "parse-json": "2.2.0",
+ "pify": "2.3.0",
+ "strip-bom": "3.0.0"
+ }
+ },
+ "path-type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+ "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+ "dev": true,
+ "requires": {
+ "pify": "2.3.0"
+ }
+ },
+ "read-pkg": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+ "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "2.0.0",
+ "normalize-package-data": "2.4.0",
+ "path-type": "2.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+ "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+ "dev": true,
+ "requires": {
+ "find-up": "2.1.0",
+ "read-pkg": "2.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ }
+ }
+ },
+ "eslint-restricted-globals": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz",
+ "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=",
+ "dev": true
+ },
+ "eslint-scope": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
+ "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
+ "dev": true,
+ "requires": {
+ "esrecurse": "4.2.0",
+ "estraverse": "4.2.0"
+ }
+ },
+ "eslint-visitor-keys": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+ "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
+ "dev": true
+ },
+ "espree": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz",
+ "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==",
+ "dev": true,
+ "requires": {
+ "acorn": "5.3.0",
+ "acorn-jsx": "3.0.1"
+ }
+ },
+ "esprima": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+ "dev": true
+ },
+ "esquery": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz",
+ "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=",
+ "dev": true,
+ "requires": {
+ "estraverse": "4.2.0"
+ }
+ },
+ "esrecurse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz",
+ "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=",
+ "dev": true,
+ "requires": {
+ "estraverse": "4.2.0",
+ "object-assign": "4.1.1"
+ }
+ },
+ "estraverse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+ "dev": true
+ },
+ "estree-walker": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.2.1.tgz",
+ "integrity": "sha1-va/oCVOD2EFNXcLs9MkXO225QS4=",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+ "dev": true
+ },
+ "event-stream": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
+ "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=",
+ "dev": true,
+ "requires": {
+ "duplexer": "0.1.1",
+ "from": "0.1.7",
+ "map-stream": "0.1.0",
+ "pause-stream": "0.0.11",
+ "split": "0.3.3",
+ "stream-combiner": "0.0.4",
+ "through": "2.3.8"
+ }
+ },
+ "execa": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+ "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "5.1.0",
+ "get-stream": "3.0.0",
+ "is-stream": "1.1.0",
+ "npm-run-path": "2.0.2",
+ "p-finally": "1.0.0",
+ "signal-exit": "3.0.2",
+ "strip-eof": "1.0.0"
+ }
+ },
+ "execall": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execall/-/execall-1.0.0.tgz",
+ "integrity": "sha1-c9CQTjlbPKsGWLCNCewlMH8pu3M=",
+ "dev": true,
+ "requires": {
+ "clone-regexp": "1.0.0"
+ }
+ },
+ "expand-brackets": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+ "dev": true,
+ "requires": {
+ "is-posix-bracket": "0.1.1"
+ }
+ },
+ "expand-range": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
+ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
+ "dev": true,
+ "requires": {
+ "fill-range": "2.2.3"
+ }
+ },
+ "extend": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+ "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+ "dev": true
+ },
+ "external-editor": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz",
+ "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==",
+ "dev": true,
+ "requires": {
+ "chardet": "0.4.2",
+ "iconv-lite": "0.4.19",
+ "tmp": "0.0.33"
+ }
+ },
+ "extglob": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ },
+ "extract-zip": {
+ "version": "1.6.6",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz",
+ "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=",
+ "dev": true,
+ "requires": {
+ "concat-stream": "1.6.0",
+ "debug": "2.6.9",
+ "mkdirp": "0.5.0",
+ "yauzl": "2.4.1"
+ },
+ "dependencies": {
+ "mkdirp": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz",
+ "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ }
+ }
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+ "dev": true
+ },
+ "fast-deep-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
+ "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=",
+ "dev": true
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "fd-slicer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
+ "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
+ "dev": true,
+ "requires": {
+ "pend": "1.2.0"
+ }
+ },
+ "figures": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "1.0.5"
+ }
+ },
+ "file-entry-cache": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
+ "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
+ "dev": true,
+ "requires": {
+ "flat-cache": "1.3.0",
+ "object-assign": "4.1.1"
+ }
+ },
+ "filename-regex": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
+ "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
+ "dev": true
+ },
+ "fill-range": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz",
+ "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=",
+ "dev": true,
+ "requires": {
+ "is-number": "2.1.0",
+ "isobject": "2.1.0",
+ "randomatic": "1.1.7",
+ "repeat-element": "1.1.2",
+ "repeat-string": "1.6.1"
+ }
+ },
+ "find-up": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+ "dev": true,
+ "requires": {
+ "path-exists": "2.1.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "flat-cache": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
+ "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
+ "dev": true,
+ "requires": {
+ "circular-json": "0.3.3",
+ "del": "2.2.2",
+ "graceful-fs": "4.1.11",
+ "write": "0.2.1"
+ }
+ },
+ "flatten": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
+ "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=",
+ "dev": true
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+ "dev": true
+ },
+ "for-own": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
+ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
+ "dev": true,
+ "requires": {
+ "for-in": "1.0.2"
+ }
+ },
+ "foreach": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+ "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
+ "dev": true
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+ "dev": true
+ },
+ "form-data": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
+ "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
+ "dev": true,
+ "requires": {
+ "asynckit": "0.4.0",
+ "combined-stream": "1.0.5",
+ "mime-types": "2.1.17"
+ }
+ },
+ "from": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
+ "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=",
+ "dev": true
+ },
+ "fs-extra": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
+ "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "jsonfile": "2.4.0",
+ "klaw": "1.3.1"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "dev": true
+ },
+ "gather-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/gather-stream/-/gather-stream-1.0.0.tgz",
+ "integrity": "sha1-szmUr0V6gRVwDUEPMXczy+egkEs=",
+ "dev": true
+ },
+ "get-caller-file": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
+ "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=",
+ "dev": true
+ },
+ "get-stdin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+ "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+ "dev": true
+ },
+ "get-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+ "dev": true
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0"
+ }
+ },
+ "glob": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
+ "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
+ "dev": true,
+ "requires": {
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "glob-base": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
+ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
+ "dev": true,
+ "requires": {
+ "glob-parent": "2.0.0",
+ "is-glob": "2.0.1"
+ }
+ },
+ "glob-parent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
+ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+ "dev": true,
+ "requires": {
+ "is-glob": "2.0.1"
+ }
+ },
+ "global-dirs": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.0.tgz",
+ "integrity": "sha1-ENNAOeDfBCcuJizyQiT3IJQ0308=",
+ "dev": true,
+ "requires": {
+ "ini": "1.3.4"
+ }
+ },
+ "globals": {
+ "version": "9.18.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+ "dev": true
+ },
+ "globby": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-4.1.0.tgz",
+ "integrity": "sha1-CA9UVJ7BuCpsYOYx/ILhIR2+lfg=",
+ "dev": true,
+ "requires": {
+ "array-union": "1.0.2",
+ "arrify": "1.0.1",
+ "glob": "6.0.4",
+ "object-assign": "4.1.1",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "globjoin": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz",
+ "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=",
+ "dev": true
+ },
+ "got": {
+ "version": "6.7.1",
+ "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
+ "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
+ "dev": true,
+ "requires": {
+ "create-error-class": "3.0.2",
+ "duplexer3": "0.1.4",
+ "get-stream": "3.0.0",
+ "is-redirect": "1.0.0",
+ "is-retry-allowed": "1.1.0",
+ "is-stream": "1.1.0",
+ "lowercase-keys": "1.0.0",
+ "safe-buffer": "5.1.1",
+ "timed-out": "4.0.1",
+ "unzip-response": "2.0.1",
+ "url-parse-lax": "1.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "dev": true
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+ "dev": true
+ },
+ "har-validator": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
+ "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
+ "dev": true,
+ "requires": {
+ "ajv": "5.2.3",
+ "har-schema": "2.0.0"
+ }
+ },
+ "has": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
+ "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=",
+ "dev": true,
+ "requires": {
+ "function-bind": "1.1.1"
+ }
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+ "dev": true
+ },
+ "hasha": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz",
+ "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=",
+ "dev": true,
+ "requires": {
+ "is-stream": "1.1.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "hawk": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
+ "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
+ "dev": true,
+ "requires": {
+ "boom": "4.3.1",
+ "cryptiles": "3.1.2",
+ "hoek": "4.2.0",
+ "sntp": "2.1.0"
+ }
+ },
+ "hoek": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
+ "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==",
+ "dev": true
+ },
+ "home-or-tmp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
+ "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
+ "dev": true,
+ "requires": {
+ "os-homedir": "1.0.2",
+ "os-tmpdir": "1.0.2"
+ }
+ },
+ "hosted-git-info": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
+ "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==",
+ "dev": true
+ },
+ "html-comment-regex": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz",
+ "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=",
+ "dev": true
+ },
+ "html-tags": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz",
+ "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=",
+ "dev": true
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "jsprim": "1.4.1",
+ "sshpk": "1.13.1"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+ "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==",
+ "dev": true
+ },
+ "ignore": {
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz",
+ "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==",
+ "dev": true
+ },
+ "import-lazy": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
+ "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=",
+ "dev": true
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "indent-string": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
+ "dev": true,
+ "requires": {
+ "repeating": "2.0.1"
+ }
+ },
+ "indexes-of": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
+ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "1.4.0",
+ "wrappy": "1.0.2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+ "dev": true
+ },
+ "ini": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
+ "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
+ "dev": true
+ },
+ "inquirer": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
+ "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "3.0.0",
+ "chalk": "2.3.0",
+ "cli-cursor": "2.1.0",
+ "cli-width": "2.2.0",
+ "external-editor": "2.1.0",
+ "figures": "2.0.0",
+ "lodash": "4.17.4",
+ "mute-stream": "0.0.7",
+ "run-async": "2.3.0",
+ "rx-lite": "4.0.8",
+ "rx-lite-aggregates": "4.0.8",
+ "string-width": "2.1.1",
+ "strip-ansi": "4.0.0",
+ "through": "2.3.8"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+ "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.5.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "3.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "invariant": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
+ "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=",
+ "dev": true,
+ "requires": {
+ "loose-envify": "1.3.1"
+ }
+ },
+ "invert-kv": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
+ "dev": true
+ },
+ "irregular-plurals": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.3.0.tgz",
+ "integrity": "sha512-njf5A+Mxb3kojuHd1DzISjjIl+XhyzovXEOyPPSzdQozq/Lf2tN27mOrAAsxEPZxpn6I4MGzs1oo9TxXxPFpaA==",
+ "dev": true
+ },
+ "is-absolute-url": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz",
+ "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=",
+ "dev": true
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+ "dev": true
+ },
+ "is-binary-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "1.10.0"
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
+ "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=",
+ "dev": true
+ },
+ "is-builtin-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+ "dev": true,
+ "requires": {
+ "builtin-modules": "1.1.1"
+ }
+ },
+ "is-callable": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz",
+ "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=",
+ "dev": true
+ },
+ "is-date-object": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
+ "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
+ "dev": true
+ },
+ "is-directory": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+ "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
+ "dev": true
+ },
+ "is-dotfile": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
+ "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=",
+ "dev": true
+ },
+ "is-equal-shallow": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
+ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
+ "dev": true,
+ "requires": {
+ "is-primitive": "2.0.0"
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+ "dev": true
+ },
+ "is-extglob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+ "dev": true
+ },
+ "is-finite": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "1.0.0"
+ }
+ },
+ "is-installed-globally": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
+ "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=",
+ "dev": true,
+ "requires": {
+ "global-dirs": "0.1.0",
+ "is-path-inside": "1.0.0"
+ }
+ },
+ "is-npm": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
+ "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=",
+ "dev": true
+ },
+ "is-number": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
+ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "is-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+ "dev": true
+ },
+ "is-path-cwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
+ "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
+ "dev": true
+ },
+ "is-path-in-cwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
+ "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=",
+ "dev": true,
+ "requires": {
+ "is-path-inside": "1.0.0"
+ }
+ },
+ "is-path-inside": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz",
+ "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=",
+ "dev": true,
+ "requires": {
+ "path-is-inside": "1.0.2"
+ }
+ },
+ "is-plain-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+ "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+ "dev": true
+ },
+ "is-posix-bracket": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
+ "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=",
+ "dev": true
+ },
+ "is-primitive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
+ "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=",
+ "dev": true
+ },
+ "is-promise": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
+ "dev": true
+ },
+ "is-redirect": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
+ "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=",
+ "dev": true
+ },
+ "is-regex": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+ "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+ "dev": true,
+ "requires": {
+ "has": "1.0.1"
+ }
+ },
+ "is-regexp": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
+ "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=",
+ "dev": true
+ },
+ "is-resolvable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz",
+ "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==",
+ "dev": true
+ },
+ "is-retry-allowed": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
+ "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "dev": true
+ },
+ "is-supported-regexp-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.0.tgz",
+ "integrity": "sha1-i1IMhfrnolM4LUsCZS4EVXbhO7g=",
+ "dev": true
+ },
+ "is-svg": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz",
+ "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=",
+ "dev": true,
+ "requires": {
+ "html-comment-regex": "1.1.1"
+ }
+ },
+ "is-symbol": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
+ "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=",
+ "dev": true
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true
+ },
+ "is-utf8": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "isnumeric": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/isnumeric/-/isnumeric-0.2.0.tgz",
+ "integrity": "sha1-ojR7o2DeGeM9D/1ZD933dVy/LmQ=",
+ "dev": true
+ },
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+ "dev": true
+ },
+ "js-base64": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.3.2.tgz",
+ "integrity": "sha512-Y2/+DnfJJXT1/FCwUebUhLWb3QihxiSC42+ctHLGogmW2jPY6LCapMdFZXRvVP2z6qyKW7s6qncE/9gSqZiArw==",
+ "dev": true
+ },
+ "js-tokens": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz",
+ "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=",
+ "dev": true,
+ "requires": {
+ "argparse": "1.0.9",
+ "esprima": "2.7.3"
+ }
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "dev": true,
+ "optional": true
+ },
+ "jsesc": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
+ "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
+ "dev": true
+ },
+ "json-parse-better-errors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz",
+ "integrity": "sha512-xyQpxeWWMKyJps9CuGJYeng6ssI5bpqS9ltQpdVQ90t4ql6NdnxFKh95JcRt2cun/DjMVNrdjniLPuMA69xmCw==",
+ "dev": true
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+ "dev": true
+ },
+ "json-schema-traverse": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+ "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
+ "dev": true
+ },
+ "json-stable-stringify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+ "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+ "dev": true,
+ "requires": {
+ "jsonify": "0.0.0"
+ }
+ },
+ "json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "dev": true
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+ "dev": true
+ },
+ "json5": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+ "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+ "dev": true
+ },
+ "jsonfile": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11"
+ }
+ },
+ "jsonfilter": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/jsonfilter/-/jsonfilter-1.1.2.tgz",
+ "integrity": "sha1-Ie987cdRk4E8dZMulqmL4gW6WhE=",
+ "dev": true,
+ "requires": {
+ "JSONStream": "0.8.4",
+ "minimist": "1.2.0",
+ "stream-combiner": "0.2.2",
+ "through2": "0.6.5"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ },
+ "stream-combiner": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz",
+ "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=",
+ "dev": true,
+ "requires": {
+ "duplexer": "0.1.1",
+ "through": "2.3.8"
+ }
+ }
+ }
+ },
+ "jsonify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+ "dev": true
+ },
+ "jsonparse": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-0.0.5.tgz",
+ "integrity": "sha1-MwVCrT8KZUZlt3jz6y2an6UHrGQ=",
+ "dev": true
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ }
+ },
+ "kew": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz",
+ "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ },
+ "klaw": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+ "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11"
+ }
+ },
+ "known-css-properties": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.2.0.tgz",
+ "integrity": "sha512-UTCzU28rRI9wkb8qSGoZa9pgWvxr4LjP2MEhi9XHb/1XMOJy0uTnIxaxzj8My/PORG+kQG6VzAcGvRw66eIOfA==",
+ "dev": true
+ },
+ "latest-version": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
+ "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=",
+ "dev": true,
+ "requires": {
+ "package-json": "4.0.1"
+ }
+ },
+ "lcid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+ "dev": true,
+ "requires": {
+ "invert-kv": "1.0.0"
+ }
+ },
+ "ldjson-stream": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ldjson-stream/-/ldjson-stream-1.2.1.tgz",
+ "integrity": "sha1-kb7O2lrE7SsX5kn7d356v6AYnCs=",
+ "dev": true,
+ "requires": {
+ "split2": "0.2.1",
+ "through2": "0.6.5"
+ }
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "1.1.2",
+ "type-check": "0.3.2"
+ }
+ },
+ "load-json-file": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "parse-json": "2.2.0",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1",
+ "strip-bom": "2.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "dev": true,
+ "requires": {
+ "p-locate": "2.0.0",
+ "path-exists": "3.0.0"
+ },
+ "dependencies": {
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ }
+ }
+ },
+ "lodash": {
+ "version": "4.17.4",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
+ "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=",
+ "dev": true
+ },
+ "lodash._reinterpolate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
+ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=",
+ "dev": true
+ },
+ "lodash.cond": {
+ "version": "4.5.2",
+ "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz",
+ "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=",
+ "dev": true
+ },
+ "lodash.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
+ "dev": true
+ },
+ "lodash.template": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz",
+ "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=",
+ "dev": true,
+ "requires": {
+ "lodash._reinterpolate": "3.0.0",
+ "lodash.templatesettings": "4.1.0"
+ }
+ },
+ "lodash.templatesettings": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz",
+ "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=",
+ "dev": true,
+ "requires": {
+ "lodash._reinterpolate": "3.0.0"
+ }
+ },
+ "lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
+ "dev": true
+ },
+ "log-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
+ "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3"
+ }
+ },
+ "loose-envify": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
+ "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
+ "dev": true,
+ "requires": {
+ "js-tokens": "3.0.2"
+ }
+ },
+ "loud-rejection": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+ "dev": true,
+ "requires": {
+ "currently-unhandled": "0.4.1",
+ "signal-exit": "3.0.2"
+ }
+ },
+ "lowercase-keys": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
+ "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
+ "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "1.0.2",
+ "yallist": "2.1.2"
+ }
+ },
+ "macaddress": {
+ "version": "0.2.8",
+ "resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz",
+ "integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=",
+ "dev": true
+ },
+ "make-dir": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz",
+ "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==",
+ "dev": true,
+ "requires": {
+ "pify": "3.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "map-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+ "dev": true
+ },
+ "map-stream": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
+ "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=",
+ "dev": true
+ },
+ "math-expression-evaluator": {
+ "version": "1.2.17",
+ "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz",
+ "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=",
+ "dev": true
+ },
+ "mathml-tag-names": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.0.1.tgz",
+ "integrity": "sha1-jUEmgWi/htEQK5gQnijlMeejRXg=",
+ "dev": true
+ },
+ "mem": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz",
+ "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "1.1.0"
+ }
+ },
+ "memorystream": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
+ "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=",
+ "dev": true
+ },
+ "meow": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
+ "dev": true,
+ "requires": {
+ "camelcase-keys": "2.1.0",
+ "decamelize": "1.2.0",
+ "loud-rejection": "1.6.0",
+ "map-obj": "1.0.1",
+ "minimist": "1.2.0",
+ "normalize-package-data": "2.4.0",
+ "object-assign": "4.1.1",
+ "read-pkg-up": "1.0.1",
+ "redent": "1.0.0",
+ "trim-newlines": "1.0.0"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ }
+ }
+ },
+ "micromatch": {
+ "version": "2.3.11",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+ "dev": true,
+ "requires": {
+ "arr-diff": "2.0.0",
+ "array-unique": "0.2.1",
+ "braces": "1.8.5",
+ "expand-brackets": "0.1.5",
+ "extglob": "0.3.2",
+ "filename-regex": "2.0.1",
+ "is-extglob": "1.0.0",
+ "is-glob": "2.0.1",
+ "kind-of": "3.2.2",
+ "normalize-path": "2.1.1",
+ "object.omit": "2.0.1",
+ "parse-glob": "3.0.4",
+ "regex-cache": "0.4.4"
+ }
+ },
+ "mime": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+ "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
+ "dev": true
+ },
+ "mime-db": {
+ "version": "1.30.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
+ "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.17",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
+ "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.30.0"
+ }
+ },
+ "mimic-fn": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz",
+ "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "1.1.8"
+ }
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "multimatch": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz",
+ "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=",
+ "dev": true,
+ "requires": {
+ "array-differ": "1.0.0",
+ "array-union": "1.0.2",
+ "arrify": "1.0.1",
+ "minimatch": "3.0.4"
+ }
+ },
+ "mute-stream": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
+ "dev": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "nested-error-stacks": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-1.0.2.tgz",
+ "integrity": "sha1-GfYZWRUZ8JZ2mlupqG5u7sgjw88=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3"
+ }
+ },
+ "node-qunit-phantomjs": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/node-qunit-phantomjs/-/node-qunit-phantomjs-2.0.0.tgz",
+ "integrity": "sha512-xZV0J8fBbe8h04IkBxLtwvGVbP0ViUhkJzjFx/tb7uWT02w6iMt5X6HDmdTZuQXBMsgahyaIGjW30l3HSlj2yA==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.3.0",
+ "minimist": "1.2.0",
+ "phantomjs-prebuilt": "2.1.16",
+ "qunit-phantomjs-runner": "2.3.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+ "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.5.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ },
+ "qunit-phantomjs-runner": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/qunit-phantomjs-runner/-/qunit-phantomjs-runner-2.3.1.tgz",
+ "integrity": "sha512-RLg51606zm6/HwZi29NciAMAqifyJE1oGg77tEuk05vEa7kuqEaI0Mkjw976Ynnq7GXurATnbFd+471c024tBQ==",
+ "dev": true,
+ "requires": {
+ "qunit-reporter-junit": "1.1.1"
+ }
+ },
+ "supports-color": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "normalize-package-data": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "2.5.0",
+ "is-builtin-module": "1.0.0",
+ "semver": "5.4.1",
+ "validate-npm-package-license": "3.0.1"
+ }
+ },
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "dev": true,
+ "requires": {
+ "remove-trailing-separator": "1.1.0"
+ }
+ },
+ "normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
+ "dev": true
+ },
+ "normalize-selector": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz",
+ "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=",
+ "dev": true
+ },
+ "normalize-url": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz",
+ "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=",
+ "dev": true,
+ "requires": {
+ "object-assign": "4.1.1",
+ "prepend-http": "1.0.4",
+ "query-string": "4.3.4",
+ "sort-keys": "1.1.2"
+ }
+ },
+ "npm-run-all": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.2.tgz",
+ "integrity": "sha512-Z2aRlajMK4SQ8u19ZA75NZZu7wupfCNQWdYosIi8S6FgBdGf/8Y6Hgyjdc8zU2cYmIRVCx1nM80tJPkdEd+UYg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "chalk": "2.3.0",
+ "cross-spawn": "5.1.0",
+ "memorystream": "0.3.1",
+ "minimatch": "3.0.4",
+ "ps-tree": "1.1.0",
+ "read-pkg": "3.0.0",
+ "shell-quote": "1.6.1",
+ "string.prototype.padend": "3.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+ "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.5.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "parse-json": "4.0.0",
+ "pify": "3.0.0",
+ "strip-bom": "3.0.0"
+ }
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dev": true,
+ "requires": {
+ "error-ex": "1.3.1",
+ "json-parse-better-errors": "1.0.1"
+ }
+ },
+ "path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "requires": {
+ "pify": "3.0.0"
+ }
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ },
+ "read-pkg": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+ "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "4.0.0",
+ "normalize-package-data": "2.4.0",
+ "path-type": "3.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+ "dev": true,
+ "requires": {
+ "path-key": "2.0.1"
+ }
+ },
+ "num2fraction": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
+ "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
+ "dev": true
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+ "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "dev": true
+ },
+ "object-keys": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
+ "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=",
+ "dev": true
+ },
+ "object.omit": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
+ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
+ "dev": true,
+ "requires": {
+ "for-own": "0.1.5",
+ "is-extendable": "0.1.1"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "onecolor": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/onecolor/-/onecolor-3.0.4.tgz",
+ "integrity": "sha1-daRvgNpseqpbTarhekcZi9llJJQ=",
+ "dev": true
+ },
+ "onetime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "1.1.0"
+ }
+ },
+ "optionator": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+ "dev": true,
+ "requires": {
+ "deep-is": "0.1.3",
+ "fast-levenshtein": "2.0.6",
+ "levn": "0.3.0",
+ "prelude-ls": "1.1.2",
+ "type-check": "0.3.2",
+ "wordwrap": "1.0.0"
+ }
+ },
+ "ora": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-1.3.0.tgz",
+ "integrity": "sha1-gAeN0rkqk0r2ajrXKluRBpTt5Ro=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "cli-cursor": "2.1.0",
+ "cli-spinners": "1.1.0",
+ "log-symbols": "1.0.2"
+ }
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+ "dev": true
+ },
+ "os-locale": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
+ "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
+ "dev": true,
+ "requires": {
+ "execa": "0.7.0",
+ "lcid": "1.0.0",
+ "mem": "1.1.0"
+ }
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "dev": true
+ },
+ "p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz",
+ "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=",
+ "dev": true
+ },
+ "p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "dev": true,
+ "requires": {
+ "p-limit": "1.1.0"
+ }
+ },
+ "p-map": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz",
+ "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==",
+ "dev": true
+ },
+ "package-json": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz",
+ "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=",
+ "dev": true,
+ "requires": {
+ "got": "6.7.1",
+ "registry-auth-token": "3.3.1",
+ "registry-url": "3.1.0",
+ "semver": "5.4.1"
+ }
+ },
+ "parse-glob": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
+ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
+ "dev": true,
+ "requires": {
+ "glob-base": "0.3.0",
+ "is-dotfile": "1.0.3",
+ "is-extglob": "1.0.0",
+ "is-glob": "2.0.1"
+ }
+ },
+ "parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "dev": true,
+ "requires": {
+ "error-ex": "1.3.1"
+ }
+ },
+ "path-exists": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+ "dev": true,
+ "requires": {
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+ "dev": true
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
+ "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
+ "dev": true
+ },
+ "path-type": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "pause-stream": {
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
+ "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=",
+ "dev": true,
+ "requires": {
+ "through": "2.3.8"
+ }
+ },
+ "pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+ "dev": true
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+ "dev": true
+ },
+ "phantomjs-prebuilt": {
+ "version": "2.1.16",
+ "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz",
+ "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=",
+ "dev": true,
+ "requires": {
+ "es6-promise": "4.1.1",
+ "extract-zip": "1.6.6",
+ "fs-extra": "1.0.0",
+ "hasha": "2.2.0",
+ "kew": "0.7.0",
+ "progress": "1.1.8",
+ "request": "2.83.0",
+ "request-progress": "2.0.1",
+ "which": "1.3.0"
+ },
+ "dependencies": {
+ "progress": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+ "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
+ "dev": true
+ }
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "dev": true
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "dev": true,
+ "requires": {
+ "pinkie": "2.0.4"
+ }
+ },
+ "pipetteur": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pipetteur/-/pipetteur-2.0.3.tgz",
+ "integrity": "sha1-GVV2CVno0aEcsqUOyD7sRwYz5J8=",
+ "dev": true,
+ "requires": {
+ "onecolor": "3.0.4",
+ "synesthesia": "1.0.1"
+ }
+ },
+ "pixrem": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pixrem/-/pixrem-4.0.1.tgz",
+ "integrity": "sha1-LaSh3m7EQjxfw3lOkwuB1EkOxoY=",
+ "dev": true,
+ "requires": {
+ "browserslist": "2.5.0",
+ "postcss": "6.0.13",
+ "reduce-css-calc": "1.3.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "pkg-dir": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz",
+ "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=",
+ "dev": true,
+ "requires": {
+ "find-up": "1.1.2"
+ }
+ },
+ "pleeease-filters": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/pleeease-filters/-/pleeease-filters-4.0.0.tgz",
+ "integrity": "sha1-ZjKy+wVkjSdY2GU4T7zteeHMrsc=",
+ "dev": true,
+ "requires": {
+ "onecolor": "3.0.4",
+ "postcss": "6.0.13"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "plur": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz",
+ "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=",
+ "dev": true,
+ "requires": {
+ "irregular-plurals": "1.3.0"
+ }
+ },
+ "pluralize": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
+ "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
+ "dev": true
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "js-base64": "2.3.2",
+ "source-map": "0.5.7",
+ "supports-color": "3.2.3"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "dev": true,
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-apply": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/postcss-apply/-/postcss-apply-0.8.0.tgz",
+ "integrity": "sha1-FOVEu7XLbxweBIhXll15rgZrE0M=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "balanced-match": "0.4.2",
+ "postcss": "6.0.13"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "balanced-match": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
+ "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-attribute-case-insensitive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-2.0.0.tgz",
+ "integrity": "sha1-lNxCLI+QmX8WvTOjZUu77AhJY7Q=",
+ "dev": true,
+ "requires": {
+ "postcss": "6.0.13",
+ "postcss-selector-parser": "2.2.3"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-calc": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz",
+ "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=",
+ "dev": true,
+ "requires": {
+ "postcss": "5.2.18",
+ "postcss-message-helpers": "2.0.0",
+ "reduce-css-calc": "1.3.0"
+ }
+ },
+ "postcss-cli": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-4.1.1.tgz",
+ "integrity": "sha1-uUvY//u3rB9i8mB+ePyTl/f2Ol0=",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "chokidar": "1.7.0",
+ "dependency-graph": "0.5.1",
+ "fs-extra": "4.0.2",
+ "get-stdin": "5.0.1",
+ "globby": "6.1.0",
+ "ora": "1.3.0",
+ "postcss": "6.0.13",
+ "postcss-load-config": "1.2.0",
+ "postcss-reporter": "5.0.0",
+ "pretty-hrtime": "1.0.3",
+ "read-cache": "1.0.0",
+ "yargs": "8.0.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "fs-extra": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.2.tgz",
+ "integrity": "sha1-+RcExT0bRh+JNFKwwwfZmXZHq2s=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "jsonfile": "4.0.0",
+ "universalify": "0.1.1"
+ }
+ },
+ "get-stdin": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz",
+ "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "globby": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+ "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
+ "dev": true,
+ "requires": {
+ "array-union": "1.0.2",
+ "glob": "7.1.2",
+ "object-assign": "4.1.1",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11"
+ }
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-color-function": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-color-function/-/postcss-color-function-4.0.0.tgz",
+ "integrity": "sha1-fgEG9Pah7LGtWzqFU6zl6Ciq4Yc=",
+ "dev": true,
+ "requires": {
+ "css-color-function": "1.3.3",
+ "postcss": "6.0.13",
+ "postcss-message-helpers": "2.0.0",
+ "postcss-value-parser": "3.3.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-color-gray": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-4.0.0.tgz",
+ "integrity": "sha1-aBvzBQl91mv+8OHmKC1dmbWsyV0=",
+ "dev": true,
+ "requires": {
+ "color": "1.0.3",
+ "postcss": "6.0.13",
+ "postcss-message-helpers": "2.0.0",
+ "reduce-function-call": "1.0.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "color": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/color/-/color-1.0.3.tgz",
+ "integrity": "sha1-5I6DLYXxTvaU+0aIEcLVz+cptV0=",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0",
+ "color-string": "1.5.2"
+ }
+ },
+ "color-string": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.2.tgz",
+ "integrity": "sha1-JuRYFLw8mny9Z1FkikFDRRSnc6k=",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3",
+ "simple-swizzle": "0.2.2"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-color-hex-alpha": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-3.0.0.tgz",
+ "integrity": "sha1-HlPmyKyyN5Vej9CLfs2xuLgwn5U=",
+ "dev": true,
+ "requires": {
+ "color": "1.0.3",
+ "postcss": "6.0.13",
+ "postcss-message-helpers": "2.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "color": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/color/-/color-1.0.3.tgz",
+ "integrity": "sha1-5I6DLYXxTvaU+0aIEcLVz+cptV0=",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0",
+ "color-string": "1.5.2"
+ }
+ },
+ "color-string": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.2.tgz",
+ "integrity": "sha1-JuRYFLw8mny9Z1FkikFDRRSnc6k=",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3",
+ "simple-swizzle": "0.2.2"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-color-hsl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-color-hsl/-/postcss-color-hsl-2.0.0.tgz",
+ "integrity": "sha1-EnA2ZvoxBDDj8wpFTawThjF9WEQ=",
+ "dev": true,
+ "requires": {
+ "postcss": "6.0.13",
+ "postcss-value-parser": "3.3.0",
+ "units-css": "0.4.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-color-hwb": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-color-hwb/-/postcss-color-hwb-3.0.0.tgz",
+ "integrity": "sha1-NAKxnvTYSXVAwftQcr6YY8qVVx4=",
+ "dev": true,
+ "requires": {
+ "color": "1.0.3",
+ "postcss": "6.0.13",
+ "postcss-message-helpers": "2.0.0",
+ "reduce-function-call": "1.0.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "color": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/color/-/color-1.0.3.tgz",
+ "integrity": "sha1-5I6DLYXxTvaU+0aIEcLVz+cptV0=",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0",
+ "color-string": "1.5.2"
+ }
+ },
+ "color-string": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.2.tgz",
+ "integrity": "sha1-JuRYFLw8mny9Z1FkikFDRRSnc6k=",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3",
+ "simple-swizzle": "0.2.2"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-color-rebeccapurple": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-3.0.0.tgz",
+ "integrity": "sha1-7rrwPTY7QwC5Z5K9MIHBntZlE9M=",
+ "dev": true,
+ "requires": {
+ "postcss": "6.0.13",
+ "postcss-value-parser": "3.3.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-color-rgb": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-color-rgb/-/postcss-color-rgb-2.0.0.tgz",
+ "integrity": "sha1-FFOcinExSUtILg3RzCZf9lFLUmM=",
+ "dev": true,
+ "requires": {
+ "postcss": "6.0.13",
+ "postcss-value-parser": "3.3.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-color-rgba-fallback": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-color-rgba-fallback/-/postcss-color-rgba-fallback-3.0.0.tgz",
+ "integrity": "sha1-N9XJNToHoJJwkSqCYGu0Kg1wLAQ=",
+ "dev": true,
+ "requires": {
+ "postcss": "6.0.13",
+ "postcss-value-parser": "3.3.0",
+ "rgb-hex": "2.1.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-colormin": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz",
+ "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=",
+ "dev": true,
+ "requires": {
+ "colormin": "1.1.2",
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ }
+ },
+ "postcss-convert-values": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz",
+ "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=",
+ "dev": true,
+ "requires": {
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ }
+ },
+ "postcss-cssnext": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-cssnext/-/postcss-cssnext-3.0.2.tgz",
+ "integrity": "sha512-jA6kGdcUMZqLUgw6MdpyNWGFhk0LIITVhC/jTnLRZLoXSTR88qT2cFOn3LbY06udt1PVdTCHDG3plBjxVKf8BQ==",
+ "dev": true,
+ "requires": {
+ "autoprefixer": "7.1.5",
+ "caniuse-api": "2.0.0",
+ "chalk": "2.1.0",
+ "pixrem": "4.0.1",
+ "pleeease-filters": "4.0.0",
+ "postcss": "6.0.13",
+ "postcss-apply": "0.8.0",
+ "postcss-attribute-case-insensitive": "2.0.0",
+ "postcss-calc": "6.0.0",
+ "postcss-color-function": "4.0.0",
+ "postcss-color-gray": "4.0.0",
+ "postcss-color-hex-alpha": "3.0.0",
+ "postcss-color-hsl": "2.0.0",
+ "postcss-color-hwb": "3.0.0",
+ "postcss-color-rebeccapurple": "3.0.0",
+ "postcss-color-rgb": "2.0.0",
+ "postcss-color-rgba-fallback": "3.0.0",
+ "postcss-custom-media": "6.0.0",
+ "postcss-custom-properties": "6.2.0",
+ "postcss-custom-selectors": "4.0.1",
+ "postcss-font-family-system-ui": "2.0.1",
+ "postcss-font-variant": "3.0.0",
+ "postcss-image-set-polyfill": "0.3.5",
+ "postcss-initial": "2.0.0",
+ "postcss-media-minmax": "3.0.0",
+ "postcss-nesting": "4.2.1",
+ "postcss-pseudo-class-any-link": "4.0.0",
+ "postcss-pseudoelements": "5.0.0",
+ "postcss-replace-overflow-wrap": "2.0.0",
+ "postcss-selector-matches": "3.0.1",
+ "postcss-selector-not": "3.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "autoprefixer": {
+ "version": "7.1.5",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.1.5.tgz",
+ "integrity": "sha512-sMN453qIm8Z+tunzYWW+Y490wWkICHhCYm/VohLjjl+N7ARSFuF5au7E6tr7oEbeeXj8mNjpSw2kxjJaO6YCOw==",
+ "dev": true,
+ "requires": {
+ "browserslist": "2.5.0",
+ "caniuse-lite": "1.0.30000744",
+ "normalize-range": "0.1.2",
+ "num2fraction": "1.2.2",
+ "postcss": "6.0.13",
+ "postcss-value-parser": "3.3.0"
+ }
+ },
+ "caniuse-api": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-2.0.0.tgz",
+ "integrity": "sha1-sd21pZZrFvSNxJmERNS7xsfZ2DQ=",
+ "dev": true,
+ "requires": {
+ "browserslist": "2.5.0",
+ "caniuse-lite": "1.0.30000744",
+ "lodash.memoize": "4.1.2",
+ "lodash.uniq": "4.5.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "postcss-calc": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-6.0.0.tgz",
+ "integrity": "sha1-toGyecbST74OM+2QRYA3BURdYTs=",
+ "dev": true,
+ "requires": {
+ "css-unit-converter": "1.1.1",
+ "postcss": "6.0.13",
+ "postcss-selector-parser": "2.2.3",
+ "reduce-css-calc": "2.0.5"
+ }
+ },
+ "reduce-css-calc": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.0.5.tgz",
+ "integrity": "sha1-M8l4OMXUxxGlwU74XOT95BSD970=",
+ "dev": true,
+ "requires": {
+ "css-unit-converter": "1.1.1",
+ "postcss-value-parser": "3.3.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-custom-media": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-6.0.0.tgz",
+ "integrity": "sha1-vlMnhBEOyylQRPtTlaGABushpzc=",
+ "dev": true,
+ "requires": {
+ "postcss": "6.0.13"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-custom-properties": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-6.2.0.tgz",
+ "integrity": "sha512-eNR2h9T9ciKMoQEORrPjH33XeN/nuvVuxArOKmHtsFbGbNss631tgTrKou3/pmjAZbA4QQkhLIkPQkIk3WW+8w==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "1.0.0",
+ "postcss": "6.0.13"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-custom-selectors": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-4.0.1.tgz",
+ "integrity": "sha1-eBOC+UxS5yfvXKR3bqKt9JphE4I=",
+ "dev": true,
+ "requires": {
+ "postcss": "6.0.13",
+ "postcss-selector-matches": "3.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-discard-comments": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz",
+ "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=",
+ "dev": true,
+ "requires": {
+ "postcss": "5.2.18"
+ }
+ },
+ "postcss-discard-duplicates": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz",
+ "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=",
+ "dev": true,
+ "requires": {
+ "postcss": "5.2.18"
+ }
+ },
+ "postcss-discard-empty": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz",
+ "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=",
+ "dev": true,
+ "requires": {
+ "postcss": "5.2.18"
+ }
+ },
+ "postcss-discard-overridden": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz",
+ "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=",
+ "dev": true,
+ "requires": {
+ "postcss": "5.2.18"
+ }
+ },
+ "postcss-discard-unused": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz",
+ "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=",
+ "dev": true,
+ "requires": {
+ "postcss": "5.2.18",
+ "uniqs": "2.0.0"
+ }
+ },
+ "postcss-filter-plugins": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz",
+ "integrity": "sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=",
+ "dev": true,
+ "requires": {
+ "postcss": "5.2.18",
+ "uniqid": "4.1.1"
+ }
+ },
+ "postcss-font-family-system-ui": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-font-family-system-ui/-/postcss-font-family-system-ui-2.0.1.tgz",
+ "integrity": "sha1-MYoHX9y4S4ZKqCOlGTXvClhy6RE=",
+ "dev": true,
+ "requires": {
+ "lodash": "4.17.4",
+ "postcss": "6.0.13",
+ "postcss-value-parser": "3.3.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-font-variant": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-3.0.0.tgz",
+ "integrity": "sha1-CMzIj2BQuoLtjvLMdsDGprQfGD4=",
+ "dev": true,
+ "requires": {
+ "postcss": "6.0.13"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-header": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-header/-/postcss-header-1.0.0.tgz",
+ "integrity": "sha512-YUcU2oHQNsNVUDPdQg6/TXBWvI7dBGf2bsLQdVlLiLM5kiGLGCcszYDlVTaicmXpKANdS1T7bxpJtCacrMButw==",
+ "dev": true,
+ "requires": {
+ "babel-register": "6.26.0",
+ "postcss": "6.0.13"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-image-set-polyfill": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/postcss-image-set-polyfill/-/postcss-image-set-polyfill-0.3.5.tgz",
+ "integrity": "sha1-Dxk0E3AM8fgr05Bm7wFtZaShgYE=",
+ "dev": true,
+ "requires": {
+ "postcss": "6.0.13",
+ "postcss-media-query-parser": "0.2.3"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-initial": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-2.0.0.tgz",
+ "integrity": "sha1-cnFfczbgu3k1HZnuZcSiU6hEG6Q=",
+ "dev": true,
+ "requires": {
+ "lodash.template": "4.4.0",
+ "postcss": "6.0.13"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-less": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-0.14.0.tgz",
+ "integrity": "sha1-xjGwicbM5CK5oQ86lY0r7dOBkyQ=",
+ "dev": true,
+ "requires": {
+ "postcss": "5.2.18"
+ }
+ },
+ "postcss-load-config": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz",
+ "integrity": "sha1-U56a/J3chiASHr+djDZz4M5Q0oo=",
+ "dev": true,
+ "requires": {
+ "cosmiconfig": "2.2.2",
+ "object-assign": "4.1.1",
+ "postcss-load-options": "1.2.0",
+ "postcss-load-plugins": "2.3.0"
+ }
+ },
+ "postcss-load-options": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz",
+ "integrity": "sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw=",
+ "dev": true,
+ "requires": {
+ "cosmiconfig": "2.2.2",
+ "object-assign": "4.1.1"
+ }
+ },
+ "postcss-load-plugins": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz",
+ "integrity": "sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI=",
+ "dev": true,
+ "requires": {
+ "cosmiconfig": "2.2.2",
+ "object-assign": "4.1.1"
+ }
+ },
+ "postcss-media-minmax": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-3.0.0.tgz",
+ "integrity": "sha1-Z1JWA3pD70C8Twdgv9BtTcadSNI=",
+ "dev": true,
+ "requires": {
+ "postcss": "6.0.13"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-media-query-parser": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz",
+ "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=",
+ "dev": true
+ },
+ "postcss-merge-idents": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz",
+ "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=",
+ "dev": true,
+ "requires": {
+ "has": "1.0.1",
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ }
+ },
+ "postcss-merge-longhand": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz",
+ "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=",
+ "dev": true,
+ "requires": {
+ "postcss": "5.2.18"
+ }
+ },
+ "postcss-merge-rules": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz",
+ "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=",
+ "dev": true,
+ "requires": {
+ "browserslist": "1.7.7",
+ "caniuse-api": "1.6.1",
+ "postcss": "5.2.18",
+ "postcss-selector-parser": "2.2.3",
+ "vendors": "1.0.1"
+ },
+ "dependencies": {
+ "browserslist": {
+ "version": "1.7.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
+ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
+ "dev": true,
+ "requires": {
+ "caniuse-db": "1.0.30000744",
+ "electron-to-chromium": "1.3.24"
+ }
+ }
+ }
+ },
+ "postcss-message-helpers": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz",
+ "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=",
+ "dev": true
+ },
+ "postcss-minify-font-values": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz",
+ "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=",
+ "dev": true,
+ "requires": {
+ "object-assign": "4.1.1",
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ }
+ },
+ "postcss-minify-gradients": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz",
+ "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=",
+ "dev": true,
+ "requires": {
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ }
+ },
+ "postcss-minify-params": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz",
+ "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=",
+ "dev": true,
+ "requires": {
+ "alphanum-sort": "1.0.2",
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0",
+ "uniqs": "2.0.0"
+ }
+ },
+ "postcss-minify-selectors": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz",
+ "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=",
+ "dev": true,
+ "requires": {
+ "alphanum-sort": "1.0.2",
+ "has": "1.0.1",
+ "postcss": "5.2.18",
+ "postcss-selector-parser": "2.2.3"
+ }
+ },
+ "postcss-nesting": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-4.2.1.tgz",
+ "integrity": "sha512-IkyWXICwagCnlaviRexi7qOdwPw3+xVVjgFfGsxmztvRVaNxAlrypOIKqDE5mxY+BVxnId1rnUKBRQoNE2VDaA==",
+ "dev": true,
+ "requires": {
+ "postcss": "6.0.13"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-normalize-charset": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz",
+ "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=",
+ "dev": true,
+ "requires": {
+ "postcss": "5.2.18"
+ }
+ },
+ "postcss-normalize-url": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz",
+ "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=",
+ "dev": true,
+ "requires": {
+ "is-absolute-url": "2.1.0",
+ "normalize-url": "1.9.1",
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ }
+ },
+ "postcss-ordered-values": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz",
+ "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=",
+ "dev": true,
+ "requires": {
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ }
+ },
+ "postcss-pseudo-class-any-link": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-4.0.0.tgz",
+ "integrity": "sha1-kVKgYT00UHIFE+iJKFS65C0O5o4=",
+ "dev": true,
+ "requires": {
+ "postcss": "6.0.13",
+ "postcss-selector-parser": "2.2.3"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-pseudoelements": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-pseudoelements/-/postcss-pseudoelements-5.0.0.tgz",
+ "integrity": "sha1-7vGU6NUkZFylIKlJ6V5RjoEkAss=",
+ "dev": true,
+ "requires": {
+ "postcss": "6.0.13"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-reduce-idents": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz",
+ "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=",
+ "dev": true,
+ "requires": {
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ }
+ },
+ "postcss-reduce-initial": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz",
+ "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=",
+ "dev": true,
+ "requires": {
+ "postcss": "5.2.18"
+ }
+ },
+ "postcss-reduce-transforms": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz",
+ "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=",
+ "dev": true,
+ "requires": {
+ "has": "1.0.1",
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0"
+ }
+ },
+ "postcss-replace-overflow-wrap": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-2.0.0.tgz",
+ "integrity": "sha1-eU22+qVPjbEAhUOSqTr0V2i04ls=",
+ "dev": true,
+ "requires": {
+ "postcss": "6.0.13"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-reporter": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-5.0.0.tgz",
+ "integrity": "sha512-rBkDbaHAu5uywbCR2XE8a25tats3xSOsGNx6mppK6Q9kSFGKc/FyAzfci+fWM2l+K402p1D0pNcfDGxeje5IKg==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "lodash": "4.17.4",
+ "log-symbols": "2.1.0",
+ "postcss": "6.0.13"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "log-symbols": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.1.0.tgz",
+ "integrity": "sha512-zLeLrzMA1A2vRF1e/0Mo+LNINzi6jzBylHj5WqvQ/WK/5WCZt8si9SyN4p9llr/HRYvVR1AoXHRHl4WTHyQAzQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0"
+ }
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-resolve-nested-selector": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz",
+ "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=",
+ "dev": true
+ },
+ "postcss-scss": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-1.0.2.tgz",
+ "integrity": "sha1-/0XPM1S4ee6JpOtoaA9GrJuxT5Q=",
+ "dev": true,
+ "requires": {
+ "postcss": "6.0.13"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-selector-matches": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-3.0.1.tgz",
+ "integrity": "sha1-5WNAEeE5UIgYYbvdWMLQER/8lqs=",
+ "dev": true,
+ "requires": {
+ "balanced-match": "0.4.2",
+ "postcss": "6.0.13"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "balanced-match": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
+ "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-selector-not": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-3.0.1.tgz",
+ "integrity": "sha1-Lk2y8JZTNsAefOx9tsYN/3ZzNdk=",
+ "dev": true,
+ "requires": {
+ "balanced-match": "0.4.2",
+ "postcss": "6.0.13"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "balanced-match": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
+ "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-selector-parser": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz",
+ "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=",
+ "dev": true,
+ "requires": {
+ "flatten": "1.0.2",
+ "indexes-of": "1.0.1",
+ "uniq": "1.0.1"
+ }
+ },
+ "postcss-sorting": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-2.1.0.tgz",
+ "integrity": "sha1-MrHpr6kTuyJaatB21QPY+YO7SoI=",
+ "dev": true,
+ "requires": {
+ "lodash": "4.17.4",
+ "postcss": "5.2.18"
+ }
+ },
+ "postcss-svgo": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz",
+ "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=",
+ "dev": true,
+ "requires": {
+ "is-svg": "2.1.0",
+ "postcss": "5.2.18",
+ "postcss-value-parser": "3.3.0",
+ "svgo": "0.7.2"
+ }
+ },
+ "postcss-unique-selectors": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz",
+ "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=",
+ "dev": true,
+ "requires": {
+ "alphanum-sort": "1.0.2",
+ "postcss": "5.2.18",
+ "uniqs": "2.0.0"
+ }
+ },
+ "postcss-url": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-7.3.0.tgz",
+ "integrity": "sha512-VBP6uf6iL3AZra23nkPkOEkS/5azj1xf/toRrjfkolfFEgg9Gyzg9UhJZeIsz12EGKZTNVeGbPa2XtaZm/iZvg==",
+ "dev": true,
+ "requires": {
+ "mime": "1.4.1",
+ "minimatch": "3.0.4",
+ "mkdirp": "0.5.1",
+ "postcss": "6.0.14",
+ "xxhashjs": "0.2.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+ "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.5.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.14",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz",
+ "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.3.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.5.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "postcss-value-parser": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz",
+ "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=",
+ "dev": true
+ },
+ "postcss-zindex": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz",
+ "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=",
+ "dev": true,
+ "requires": {
+ "has": "1.0.1",
+ "postcss": "5.2.18",
+ "uniqs": "2.0.0"
+ }
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "dev": true
+ },
+ "prepend-http": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
+ "dev": true
+ },
+ "preserve": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
+ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
+ "dev": true
+ },
+ "pretty-hrtime": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
+ "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
+ "dev": true
+ },
+ "private": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz",
+ "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=",
+ "dev": true
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+ "dev": true
+ },
+ "progress": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
+ "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
+ "dev": true
+ },
+ "ps-tree": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz",
+ "integrity": "sha1-tCGyQUDWID8e08dplrRCewjowBQ=",
+ "dev": true,
+ "requires": {
+ "event-stream": "3.3.4"
+ }
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+ "dev": true
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+ "dev": true
+ },
+ "q": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz",
+ "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+ "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
+ "dev": true
+ },
+ "query-string": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
+ "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
+ "dev": true,
+ "requires": {
+ "object-assign": "4.1.1",
+ "strict-uri-encode": "1.1.0"
+ }
+ },
+ "qunit-reporter-junit": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/qunit-reporter-junit/-/qunit-reporter-junit-1.1.1.tgz",
+ "integrity": "sha1-7rYiZFeJaZPnlaEZQPGK9q+lebQ=",
+ "dev": true
+ },
+ "randomatic": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz",
+ "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==",
+ "dev": true,
+ "requires": {
+ "is-number": "3.0.0",
+ "kind-of": "4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ }
+ }
+ },
+ "rc": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz",
+ "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=",
+ "dev": true,
+ "requires": {
+ "deep-extend": "0.4.2",
+ "ini": "1.3.4",
+ "minimist": "1.2.0",
+ "strip-json-comments": "2.0.1"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ }
+ }
+ },
+ "read-cache": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+ "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=",
+ "dev": true,
+ "requires": {
+ "pify": "2.3.0"
+ }
+ },
+ "read-file-stdin": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/read-file-stdin/-/read-file-stdin-0.2.1.tgz",
+ "integrity": "sha1-JezP86FTtoCa+ssj7hU4fbng7mE=",
+ "dev": true,
+ "requires": {
+ "gather-stream": "1.0.0"
+ }
+ },
+ "read-pkg": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "1.1.0",
+ "normalize-package-data": "2.4.0",
+ "path-type": "1.1.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+ "dev": true,
+ "requires": {
+ "find-up": "1.1.2",
+ "read-pkg": "1.1.0"
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
+ "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "1.0.7",
+ "safe-buffer": "5.1.1",
+ "string_decoder": "1.0.3",
+ "util-deprecate": "1.0.2"
+ }
+ },
+ "readdirp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
+ "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "minimatch": "3.0.4",
+ "readable-stream": "2.3.3",
+ "set-immediate-shim": "1.0.1"
+ }
+ },
+ "redent": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+ "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
+ "dev": true,
+ "requires": {
+ "indent-string": "2.1.0",
+ "strip-indent": "1.0.1"
+ }
+ },
+ "reduce-css-calc": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz",
+ "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=",
+ "dev": true,
+ "requires": {
+ "balanced-match": "0.4.2",
+ "math-expression-evaluator": "1.2.17",
+ "reduce-function-call": "1.0.2"
+ },
+ "dependencies": {
+ "balanced-match": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
+ "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
+ "dev": true
+ }
+ }
+ },
+ "reduce-function-call": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz",
+ "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=",
+ "dev": true,
+ "requires": {
+ "balanced-match": "0.4.2"
+ },
+ "dependencies": {
+ "balanced-match": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
+ "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
+ "dev": true
+ }
+ }
+ },
+ "regenerate": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz",
+ "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==",
+ "dev": true
+ },
+ "regenerator-runtime": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz",
+ "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==",
+ "dev": true
+ },
+ "regenerator-transform": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz",
+ "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "6.26.0",
+ "babel-types": "6.26.0",
+ "private": "0.1.7"
+ }
+ },
+ "regex-cache": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
+ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
+ "dev": true,
+ "requires": {
+ "is-equal-shallow": "0.1.3"
+ }
+ },
+ "regexpu-core": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
+ "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=",
+ "dev": true,
+ "requires": {
+ "regenerate": "1.3.3",
+ "regjsgen": "0.2.0",
+ "regjsparser": "0.1.5"
+ }
+ },
+ "registry-auth-token": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz",
+ "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=",
+ "dev": true,
+ "requires": {
+ "rc": "1.2.2",
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "registry-url": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
+ "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
+ "dev": true,
+ "requires": {
+ "rc": "1.2.2"
+ }
+ },
+ "regjsgen": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
+ "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
+ "dev": true
+ },
+ "regjsparser": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
+ "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
+ "dev": true,
+ "requires": {
+ "jsesc": "0.5.0"
+ },
+ "dependencies": {
+ "jsesc": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+ "dev": true
+ }
+ }
+ },
+ "remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+ "dev": true
+ },
+ "repeat-element": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
+ "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
+ "dev": true
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+ "dev": true
+ },
+ "repeating": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+ "dev": true,
+ "requires": {
+ "is-finite": "1.0.2"
+ }
+ },
+ "request": {
+ "version": "2.83.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
+ "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "0.7.0",
+ "aws4": "1.6.0",
+ "caseless": "0.12.0",
+ "combined-stream": "1.0.5",
+ "extend": "3.0.1",
+ "forever-agent": "0.6.1",
+ "form-data": "2.3.1",
+ "har-validator": "5.0.3",
+ "hawk": "6.0.2",
+ "http-signature": "1.2.0",
+ "is-typedarray": "1.0.0",
+ "isstream": "0.1.2",
+ "json-stringify-safe": "5.0.1",
+ "mime-types": "2.1.17",
+ "oauth-sign": "0.8.2",
+ "performance-now": "2.1.0",
+ "qs": "6.5.1",
+ "safe-buffer": "5.1.1",
+ "stringstream": "0.0.5",
+ "tough-cookie": "2.3.3",
+ "tunnel-agent": "0.6.0",
+ "uuid": "3.1.0"
+ }
+ },
+ "request-progress": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz",
+ "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=",
+ "dev": true,
+ "requires": {
+ "throttleit": "1.0.0"
+ }
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "dev": true
+ },
+ "require-from-string": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
+ "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=",
+ "dev": true
+ },
+ "require-main-filename": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
+ "dev": true
+ },
+ "require-relative": {
+ "version": "0.8.7",
+ "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz",
+ "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=",
+ "dev": true
+ },
+ "require-uncached": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
+ "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
+ "dev": true,
+ "requires": {
+ "caller-path": "0.1.0",
+ "resolve-from": "1.0.1"
+ }
+ },
+ "resolve": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz",
+ "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==",
+ "dev": true,
+ "requires": {
+ "path-parse": "1.0.5"
+ }
+ },
+ "resolve-from": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
+ "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
+ "dev": true
+ },
+ "restore-cursor": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+ "dev": true,
+ "requires": {
+ "onetime": "2.0.1",
+ "signal-exit": "3.0.2"
+ }
+ },
+ "rgb": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/rgb/-/rgb-0.1.0.tgz",
+ "integrity": "sha1-vieykej+/+rBvZlylyG/pA/AN7U=",
+ "dev": true
+ },
+ "rgb-hex": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/rgb-hex/-/rgb-hex-2.1.0.tgz",
+ "integrity": "sha1-x3PF/iJoolV42SU5qCp6XOU77aY=",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "dev": true,
+ "requires": {
+ "glob": "7.1.2"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ }
+ }
+ },
+ "rollup": {
+ "version": "0.53.3",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.53.3.tgz",
+ "integrity": "sha512-MADFV0jpoh1QDB6U0U6YamGihGetxHEYgwTcGsc7map6JFIydPEfGNshK+ozxv1RKeUOQKn1vRb85IAcdjL22Q==",
+ "dev": true
+ },
+ "rollup-plugin-babel": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-3.0.3.tgz",
+ "integrity": "sha512-5kzM/Rr4jQSRPLc2eN5NuD+CI/6AAy7S1O18Ogu4U3nq1Q42VJn0C9EMtqnvxtfwf1XrezOtdA9ro1VZI5B0mA==",
+ "dev": true,
+ "requires": {
+ "rollup-pluginutils": "1.5.2"
+ }
+ },
+ "rollup-pluginutils": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz",
+ "integrity": "sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg=",
+ "dev": true,
+ "requires": {
+ "estree-walker": "0.2.1",
+ "minimatch": "3.0.4"
+ }
+ },
+ "rollup-watch": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/rollup-watch/-/rollup-watch-4.3.1.tgz",
+ "integrity": "sha512-6yjnIwfjpSrqA8IafyIu7fsEyeImNR4aDjA1bQ7KWeVuiA+Clfsx8+PGQkyABWIQzmauQ//tIJ5wAxLXsXs8qQ==",
+ "dev": true,
+ "requires": {
+ "chokidar": "1.7.0",
+ "require-relative": "0.8.7",
+ "rollup-pluginutils": "2.0.1"
+ },
+ "dependencies": {
+ "estree-walker": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.3.1.tgz",
+ "integrity": "sha1-5rGlHPcpJSTnI3wxLl/mZgwc4ao=",
+ "dev": true
+ },
+ "rollup-pluginutils": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.0.1.tgz",
+ "integrity": "sha1-fslbNXP2VDpGpkYb2afFRFJdD8A=",
+ "dev": true,
+ "requires": {
+ "estree-walker": "0.3.1",
+ "micromatch": "2.3.11"
+ }
+ }
+ }
+ },
+ "run-async": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
+ "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
+ "dev": true,
+ "requires": {
+ "is-promise": "2.1.0"
+ }
+ },
+ "rx-lite": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
+ "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
+ "dev": true
+ },
+ "rx-lite-aggregates": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
+ "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
+ "dev": true,
+ "requires": {
+ "rx-lite": "4.0.8"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
+ "dev": true
+ },
+ "sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+ "dev": true
+ },
+ "semver": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
+ "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
+ "dev": true
+ },
+ "semver-diff": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
+ "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
+ "dev": true,
+ "requires": {
+ "semver": "5.4.1"
+ }
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+ "dev": true
+ },
+ "set-immediate-shim": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
+ "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true
+ },
+ "shell-quote": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz",
+ "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=",
+ "dev": true,
+ "requires": {
+ "array-filter": "0.0.1",
+ "array-map": "0.0.0",
+ "array-reduce": "0.0.0",
+ "jsonify": "0.0.0"
+ }
+ },
+ "sigmund": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
+ "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+ "dev": true
+ },
+ "simple-swizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+ "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "0.3.1"
+ },
+ "dependencies": {
+ "is-arrayish": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.1.tgz",
+ "integrity": "sha1-wt/DhquqDD4zxI2z/ocFnmkGXv0=",
+ "dev": true
+ }
+ }
+ },
+ "slash": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+ "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
+ "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "2.0.0"
+ }
+ },
+ "sntp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
+ "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
+ "dev": true,
+ "requires": {
+ "hoek": "4.2.0"
+ }
+ },
+ "sort-keys": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
+ "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
+ "dev": true,
+ "requires": {
+ "is-plain-obj": "1.1.0"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ },
+ "source-map-support": {
+ "version": "0.4.18",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
+ "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
+ "dev": true,
+ "requires": {
+ "source-map": "0.5.7"
+ }
+ },
+ "spdx-correct": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
+ "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
+ "dev": true,
+ "requires": {
+ "spdx-license-ids": "1.2.2"
+ }
+ },
+ "spdx-expression-parse": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
+ "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=",
+ "dev": true
+ },
+ "spdx-license-ids": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
+ "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=",
+ "dev": true
+ },
+ "specificity": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.3.2.tgz",
+ "integrity": "sha512-Nc/QN/A425Qog7j9aHmwOrlwX2e7pNI47ciwxwy4jOlvbbMHkNNJchit+FX+UjF3IAdiaaV5BKeWuDUnws6G1A==",
+ "dev": true
+ },
+ "split": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
+ "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=",
+ "dev": true,
+ "requires": {
+ "through": "2.3.8"
+ }
+ },
+ "split2": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-0.2.1.tgz",
+ "integrity": "sha1-At2smtwD7Au3jBKC7Aecpuha6QA=",
+ "dev": true,
+ "requires": {
+ "through2": "0.6.5"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "sshpk": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
+ "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
+ "dev": true,
+ "requires": {
+ "asn1": "0.2.3",
+ "assert-plus": "1.0.0",
+ "bcrypt-pbkdf": "1.0.1",
+ "dashdash": "1.14.1",
+ "ecc-jsbn": "0.1.1",
+ "getpass": "0.1.7",
+ "jsbn": "0.1.1",
+ "tweetnacl": "0.14.5"
+ }
+ },
+ "stdin": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/stdin/-/stdin-0.0.1.tgz",
+ "integrity": "sha1-0wQZgarsPf28d6GzjWNy449ftx4=",
+ "dev": true
+ },
+ "stream-combiner": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
+ "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=",
+ "dev": true,
+ "requires": {
+ "duplexer": "0.1.1"
+ }
+ },
+ "strict-uri-encode": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+ "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "2.0.0",
+ "strip-ansi": "4.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "3.0.0"
+ }
+ }
+ }
+ },
+ "string.prototype.padend": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz",
+ "integrity": "sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA=",
+ "dev": true,
+ "requires": {
+ "define-properties": "1.1.2",
+ "es-abstract": "1.9.0",
+ "function-bind": "1.1.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "stringstream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+ "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "strip-bom": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+ "dev": true,
+ "requires": {
+ "is-utf8": "0.2.1"
+ }
+ },
+ "strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+ "dev": true
+ },
+ "strip-indent": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
+ "dev": true,
+ "requires": {
+ "get-stdin": "4.0.1"
+ }
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "dev": true
+ },
+ "style-search": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz",
+ "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=",
+ "dev": true
+ },
+ "stylefmt": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/stylefmt/-/stylefmt-6.0.0.tgz",
+ "integrity": "sha1-yFHpwteLiplQL3S6PYY7MBY+7JM=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "css-color-list": "0.0.1",
+ "diff": "3.4.0",
+ "editorconfig": "0.13.3",
+ "globby": "6.1.0",
+ "minimist": "1.2.0",
+ "postcss": "6.0.13",
+ "postcss-scss": "1.0.2",
+ "postcss-sorting": "2.1.0",
+ "postcss-value-parser": "3.3.0",
+ "stdin": "0.0.1",
+ "stylelint": "7.13.0",
+ "stylelint-order": "0.4.4"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "globby": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+ "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
+ "dev": true,
+ "requires": {
+ "array-union": "1.0.2",
+ "glob": "7.1.2",
+ "object-assign": "4.1.1",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "6.0.13",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.13.tgz",
+ "integrity": "sha512-nHsrD1PPTMSJDfU+osVsLtPkSP9YGeoOz4FDLN4r1DW4N5vqL1J+gACzTQHsfwIiWG/0/nV4yCzjTMo1zD8U1g==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.1.0",
+ "source-map": "0.6.1",
+ "supports-color": "4.4.0"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ }
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "stylehacks": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-2.3.2.tgz",
+ "integrity": "sha1-ZMg+BDimjJ7fRJ6MVSp9mrYAmws=",
+ "dev": true,
+ "requires": {
+ "browserslist": "1.7.7",
+ "chalk": "1.1.3",
+ "log-symbols": "1.0.2",
+ "minimist": "1.2.0",
+ "plur": "2.1.2",
+ "postcss": "5.2.18",
+ "postcss-reporter": "1.4.1",
+ "postcss-selector-parser": "2.2.3",
+ "read-file-stdin": "0.2.1",
+ "text-table": "0.2.0",
+ "write-file-stdout": "0.0.2"
+ },
+ "dependencies": {
+ "browserslist": {
+ "version": "1.7.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
+ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
+ "dev": true,
+ "requires": {
+ "caniuse-db": "1.0.30000744",
+ "electron-to-chromium": "1.3.24"
+ }
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ },
+ "postcss-reporter": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-1.4.1.tgz",
+ "integrity": "sha1-wTbwpbFhkV83ndN2XGEHX357mvI=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "lodash": "4.17.4",
+ "log-symbols": "1.0.2",
+ "postcss": "5.2.18"
+ }
+ }
+ }
+ },
+ "stylelint": {
+ "version": "7.13.0",
+ "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-7.13.0.tgz",
+ "integrity": "sha1-ER+Xttpy53XICADWu29fhpmXeF0=",
+ "dev": true,
+ "requires": {
+ "autoprefixer": "6.7.7",
+ "balanced-match": "0.4.2",
+ "chalk": "2.1.0",
+ "colorguard": "1.2.0",
+ "cosmiconfig": "2.2.2",
+ "debug": "2.6.9",
+ "doiuse": "2.6.0",
+ "execall": "1.0.0",
+ "file-entry-cache": "2.0.0",
+ "get-stdin": "5.0.1",
+ "globby": "6.1.0",
+ "globjoin": "0.1.4",
+ "html-tags": "2.0.0",
+ "ignore": "3.3.5",
+ "imurmurhash": "0.1.4",
+ "known-css-properties": "0.2.0",
+ "lodash": "4.17.4",
+ "log-symbols": "1.0.2",
+ "mathml-tag-names": "2.0.1",
+ "meow": "3.7.0",
+ "micromatch": "2.3.11",
+ "normalize-selector": "0.2.0",
+ "pify": "2.3.0",
+ "postcss": "5.2.18",
+ "postcss-less": "0.14.0",
+ "postcss-media-query-parser": "0.2.3",
+ "postcss-reporter": "3.0.0",
+ "postcss-resolve-nested-selector": "0.1.1",
+ "postcss-scss": "0.4.1",
+ "postcss-selector-parser": "2.2.3",
+ "postcss-value-parser": "3.3.0",
+ "resolve-from": "3.0.0",
+ "specificity": "0.3.2",
+ "string-width": "2.1.1",
+ "style-search": "0.1.0",
+ "stylehacks": "2.3.2",
+ "sugarss": "0.2.0",
+ "svg-tags": "1.0.0",
+ "table": "4.0.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "balanced-match": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
+ "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "get-stdin": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz",
+ "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "globby": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+ "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
+ "dev": true,
+ "requires": {
+ "array-union": "1.0.2",
+ "glob": "7.1.2",
+ "object-assign": "4.1.1",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "postcss-reporter": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-3.0.0.tgz",
+ "integrity": "sha1-CeoPN6RExWk4eGBuCbAY6+/3z48=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "lodash": "4.17.4",
+ "log-symbols": "1.0.2",
+ "postcss": "5.2.18"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "2.2.1",
+ "escape-string-regexp": "1.0.5",
+ "has-ansi": "2.0.0",
+ "strip-ansi": "3.0.1",
+ "supports-color": "2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "postcss-scss": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-0.4.1.tgz",
+ "integrity": "sha1-rXcbgfD3L19IRdCKpg+TVXZT1Uw=",
+ "dev": true,
+ "requires": {
+ "postcss": "5.2.18"
+ }
+ },
+ "resolve-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "stylelint-order": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-0.4.4.tgz",
+ "integrity": "sha1-2338oFQbUGIBDH4uIedFeR/AiKw=",
+ "dev": true,
+ "requires": {
+ "lodash": "4.17.4",
+ "postcss": "5.2.18",
+ "stylelint": "7.13.0"
+ }
+ },
+ "sugarss": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-0.2.0.tgz",
+ "integrity": "sha1-rDQjdWMyfG/4l7ZHQr9q7BkK054=",
+ "dev": true,
+ "requires": {
+ "postcss": "5.2.18"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ },
+ "svg-tags": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
+ "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=",
+ "dev": true
+ },
+ "svgo": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz",
+ "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=",
+ "dev": true,
+ "requires": {
+ "coa": "1.0.4",
+ "colors": "1.1.2",
+ "csso": "2.3.2",
+ "js-yaml": "3.7.0",
+ "mkdirp": "0.5.1",
+ "sax": "1.2.4",
+ "whet.extend": "0.9.9"
+ }
+ },
+ "synesthesia": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/synesthesia/-/synesthesia-1.0.1.tgz",
+ "integrity": "sha1-XvlepUjA1cbm+btLDQcx3/hkp3c=",
+ "dev": true,
+ "requires": {
+ "css-color-names": "0.0.3"
+ },
+ "dependencies": {
+ "css-color-names": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.3.tgz",
+ "integrity": "sha1-3gzvFvTYqoIioyDVttfpu62nufY=",
+ "dev": true
+ }
+ }
+ },
+ "table": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
+ "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
+ "dev": true,
+ "requires": {
+ "ajv": "5.2.3",
+ "ajv-keywords": "2.1.0",
+ "chalk": "2.1.0",
+ "lodash": "4.17.4",
+ "slice-ansi": "1.0.0",
+ "string-width": "2.1.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+ "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "term-size": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
+ "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=",
+ "dev": true,
+ "requires": {
+ "execa": "0.7.0"
+ }
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "throttleit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
+ "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=",
+ "dev": true
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
+ "through2": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
+ "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "1.0.34",
+ "xtend": "4.0.1"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "1.0.34",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "1.0.2",
+ "inherits": "2.0.3",
+ "isarray": "0.0.1",
+ "string_decoder": "0.10.31"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
+ }
+ }
+ },
+ "timed-out": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+ "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
+ "dev": true
+ },
+ "tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "dev": true,
+ "requires": {
+ "os-tmpdir": "1.0.2"
+ }
+ },
+ "to-fast-properties": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
+ "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
+ "dev": true
+ },
+ "tough-cookie": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
+ "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
+ "dev": true,
+ "requires": {
+ "punycode": "1.4.1"
+ }
+ },
+ "trim-newlines": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+ "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
+ "dev": true
+ },
+ "trim-right": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
+ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
+ "dev": true
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "dev": true,
+ "optional": true
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "1.1.2"
+ }
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+ "dev": true
+ },
+ "uglify-js": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.4.tgz",
+ "integrity": "sha512-hfIwuAQI5dlXP30UtdmWoYF9k+ypVqBXIdmd6ZKBiaNHHvA8ty7ZloMe3+7S5AEKVkxHbjByl4DfRHQ7QpZquw==",
+ "dev": true,
+ "requires": {
+ "commander": "2.12.2",
+ "source-map": "0.6.1"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.12.2",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz",
+ "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "uniq": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
+ "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
+ "dev": true
+ },
+ "uniqid": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-4.1.1.tgz",
+ "integrity": "sha1-iSIN32t1GuUrX3JISGNShZa7hME=",
+ "dev": true,
+ "requires": {
+ "macaddress": "0.2.8"
+ }
+ },
+ "uniqs": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz",
+ "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=",
+ "dev": true
+ },
+ "unique-string": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
+ "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
+ "dev": true,
+ "requires": {
+ "crypto-random-string": "1.0.0"
+ }
+ },
+ "units-css": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/units-css/-/units-css-0.4.0.tgz",
+ "integrity": "sha1-1iKGU6UZg9fBb/KPi53Dsf/tOgc=",
+ "dev": true,
+ "requires": {
+ "isnumeric": "0.2.0",
+ "viewport-dimensions": "0.2.0"
+ }
+ },
+ "universalify": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",
+ "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=",
+ "dev": true
+ },
+ "unzip-response": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
+ "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=",
+ "dev": true
+ },
+ "update-notifier": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.3.0.tgz",
+ "integrity": "sha1-TognpruRUUCrCTVZ1wFOPruDdFE=",
+ "dev": true,
+ "requires": {
+ "boxen": "1.2.2",
+ "chalk": "2.3.0",
+ "configstore": "3.1.1",
+ "import-lazy": "2.1.0",
+ "is-installed-globally": "0.1.0",
+ "is-npm": "1.0.0",
+ "latest-version": "3.1.0",
+ "semver-diff": "2.1.0",
+ "xdg-basedir": "3.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+ "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "4.5.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "dev": true,
+ "requires": {
+ "has-flag": "2.0.0"
+ }
+ }
+ }
+ },
+ "url-parse-lax": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+ "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+ "dev": true,
+ "requires": {
+ "prepend-http": "1.0.4"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ },
+ "uuid": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
+ "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==",
+ "dev": true
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
+ "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
+ "dev": true,
+ "requires": {
+ "spdx-correct": "1.0.2",
+ "spdx-expression-parse": "1.0.4"
+ }
+ },
+ "vendors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.1.tgz",
+ "integrity": "sha1-N61zyO5Bf7PVgOeFMSMH0nSEfyI=",
+ "dev": true
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "1.3.0"
+ }
+ },
+ "viewport-dimensions": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/viewport-dimensions/-/viewport-dimensions-0.2.0.tgz",
+ "integrity": "sha1-3nQHR9tTh/0XJfUXXpG6x2r982w=",
+ "dev": true
+ },
+ "whet.extend": {
+ "version": "0.9.9",
+ "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz",
+ "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=",
+ "dev": true
+ },
+ "which": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
+ "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
+ "dev": true,
+ "requires": {
+ "isexe": "2.0.0"
+ }
+ },
+ "which-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+ "dev": true
+ },
+ "widest-line": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz",
+ "integrity": "sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw=",
+ "dev": true,
+ "requires": {
+ "string-width": "1.0.2"
+ },
+ "dependencies": {
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "1.1.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "strip-ansi": "3.0.1"
+ }
+ }
+ }
+ },
+ "window-size": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz",
+ "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=",
+ "dev": true
+ },
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+ "dev": true
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "dev": true,
+ "requires": {
+ "string-width": "1.0.2",
+ "strip-ansi": "3.0.1"
+ },
+ "dependencies": {
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "1.0.1"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "1.1.0",
+ "is-fullwidth-code-point": "1.0.0",
+ "strip-ansi": "3.0.1"
+ }
+ }
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "write": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
+ "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
+ "dev": true,
+ "requires": {
+ "mkdirp": "0.5.1"
+ }
+ },
+ "write-file-atomic": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz",
+ "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "imurmurhash": "0.1.4",
+ "signal-exit": "3.0.2"
+ }
+ },
+ "write-file-stdout": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/write-file-stdout/-/write-file-stdout-0.0.2.tgz",
+ "integrity": "sha1-wlLXx8WxtAKJdjDjRTx7/mkNnKE=",
+ "dev": true
+ },
+ "xdg-basedir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
+ "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=",
+ "dev": true
+ },
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+ "dev": true
+ },
+ "xxhashjs": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.1.tgz",
+ "integrity": "sha1-m76b6JYUKXbfo0wGGy0GjEPTDeA=",
+ "dev": true,
+ "requires": {
+ "cuint": "0.2.2"
+ }
+ },
+ "y18n": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
+ "dev": true
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz",
+ "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=",
+ "dev": true,
+ "requires": {
+ "camelcase": "4.1.0",
+ "cliui": "3.2.0",
+ "decamelize": "1.2.0",
+ "get-caller-file": "1.0.2",
+ "os-locale": "2.1.0",
+ "read-pkg-up": "2.0.0",
+ "require-directory": "2.1.1",
+ "require-main-filename": "1.0.1",
+ "set-blocking": "2.0.0",
+ "string-width": "2.1.1",
+ "which-module": "2.0.0",
+ "y18n": "3.2.1",
+ "yargs-parser": "7.0.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "requires": {
+ "locate-path": "2.0.0"
+ }
+ },
+ "load-json-file": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+ "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "4.1.11",
+ "parse-json": "2.2.0",
+ "pify": "2.3.0",
+ "strip-bom": "3.0.0"
+ }
+ },
+ "path-type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+ "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+ "dev": true,
+ "requires": {
+ "pify": "2.3.0"
+ }
+ },
+ "read-pkg": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+ "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "2.0.0",
+ "normalize-package-data": "2.4.0",
+ "path-type": "2.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+ "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+ "dev": true,
+ "requires": {
+ "find-up": "2.1.0",
+ "read-pkg": "2.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ }
+ }
+ },
+ "yargs-parser": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz",
+ "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=",
+ "dev": true,
+ "requires": {
+ "camelcase": "4.1.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
+ }
+ }
+ },
+ "yauzl": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
+ "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
+ "dev": true,
+ "requires": {
+ "fd-slicer": "1.0.1"
+ }
+ }
+ }
+}
diff --git a/library/cropperjs/package.json b/library/cropperjs/package.json
new file mode 100644
index 000000000..f94100981
--- /dev/null
+++ b/library/cropperjs/package.json
@@ -0,0 +1,76 @@
+{
+ "name": "cropperjs",
+ "description": "JavaScript image cropper.",
+ "version": "1.2.2",
+ "main": "dist/cropper.common.js",
+ "module": "dist/cropper.esm.js",
+ "browser": "dist/cropper.js",
+ "style": "dist/cropper.css",
+ "repository": "fengyuanchen/cropperjs",
+ "homepage": "https://fengyuanchen.github.io/cropperjs",
+ "license": "MIT",
+ "author": {
+ "name": "Chen Fengyuan",
+ "url": "http://chenfengyuan.com"
+ },
+ "files": [
+ "src",
+ "dist"
+ ],
+ "keywords": [
+ "image",
+ "crop",
+ "cropping",
+ "move",
+ "zoom",
+ "rotate",
+ "scale",
+ "cropper",
+ "cropperjs",
+ "cropper.js",
+ "html",
+ "css",
+ "javascript",
+ "front-end",
+ "web",
+ "development"
+ ],
+ "scripts": {
+ "build": "npm run build:css && npm run build:js",
+ "build:css": "postcss src/css/cropper.css -o dist/cropper.css --no-map",
+ "build:js": "rollup -c",
+ "clear": "del-cli dist",
+ "compress": "npm run compress:css && npm run compress:js",
+ "compress:css": "postcss dist/cropper.css -u cssnano -o dist/cropper.min.css --no-map",
+ "compress:js": "uglifyjs dist/cropper.js -o dist/cropper.min.js -c -m --comments /^!/",
+ "copy": "cpy dist/cropper.css docs/css",
+ "lint": "eslint src/js --fix",
+ "release": "npm run clear && npm run lint && npm run build && npm run compress && npm run copy && npm test",
+ "start": "npm-run-all --parallel watch:*",
+ "test": "node-qunit-phantomjs test/index.html --timeout 10",
+ "watch:css": "postcss src/css/cropper.css -o docs/css/cropper.css -m -w",
+ "watch:js": "rollup -c -m -w"
+ },
+ "devDependencies": {
+ "babel-core": "^6.26.0",
+ "babel-plugin-external-helpers": "^6.22.0",
+ "babel-preset-env": "^1.6.1",
+ "cpy-cli": "^1.0.1",
+ "cssnano": "^3.10.0",
+ "del-cli": "^1.1.0",
+ "eslint": "^4.14.0",
+ "eslint-config-airbnb-base": "^12.1.0",
+ "eslint-plugin-import": "^2.8.0",
+ "node-qunit-phantomjs": "^2.0.0",
+ "npm-run-all": "^4.1.2",
+ "postcss-cli": "^4.1.1",
+ "postcss-cssnext": "^3.0.2",
+ "postcss-header": "^1.0.0",
+ "postcss-url": "^7.3.0",
+ "rollup": "^0.53.3",
+ "rollup-plugin-babel": "^3.0.3",
+ "rollup-watch": "^4.3.1",
+ "stylefmt": "^6.0.0",
+ "uglify-js": "^3.3.4"
+ }
+}
diff --git a/library/cropperjs/postcss.config.js b/library/cropperjs/postcss.config.js
new file mode 100644
index 000000000..af7ec6024
--- /dev/null
+++ b/library/cropperjs/postcss.config.js
@@ -0,0 +1,14 @@
+const rollupConfig = require('./rollup.config');
+
+module.exports = {
+ plugins: {
+ 'postcss-cssnext': {},
+ 'postcss-url': {
+ url: 'inline',
+ },
+ 'postcss-header': {
+ header: rollupConfig.banner,
+ },
+ stylefmt: {},
+ },
+};
diff --git a/library/cropperjs/rollup.config.js b/library/cropperjs/rollup.config.js
new file mode 100644
index 000000000..b792a79a7
--- /dev/null
+++ b/library/cropperjs/rollup.config.js
@@ -0,0 +1,50 @@
+const babel = require('rollup-plugin-babel');
+const pkg = require('./package');
+
+const now = new Date();
+const banner = `/*!
+ * Cropper.js v${pkg.version}
+ * https://github.com/${pkg.repository}
+ *
+ * Copyright (c) 2015-${now.getFullYear()} ${pkg.author.name}
+ * Released under the ${pkg.license} license
+ *
+ * Date: ${now.toISOString()}
+ */
+`;
+
+module.exports = {
+ // Export banner for PostCSS
+ banner,
+ input: 'src/js/cropper.js',
+ output: [
+ {
+ banner,
+ file: 'dist/cropper.js',
+ format: 'umd',
+ name: 'Cropper',
+ },
+ {
+ banner,
+ file: 'dist/cropper.common.js',
+ format: 'cjs',
+ },
+ {
+ banner,
+ file: 'dist/cropper.esm.js',
+ format: 'es',
+ },
+ {
+ banner,
+ file: 'docs/js/cropper.js',
+ format: 'umd',
+ name: 'Cropper',
+ },
+ ],
+ plugins: [
+ babel({
+ exclude: 'node_modules/**',
+ plugins: ['external-helpers'],
+ }),
+ ],
+};
diff --git a/library/cropperjs/src/css/cropper.css b/library/cropperjs/src/css/cropper.css
new file mode 100644
index 000000000..d09c4f182
--- /dev/null
+++ b/library/cropperjs/src/css/cropper.css
@@ -0,0 +1,290 @@
+:root {
+ --blue: #39f;
+}
+
+.cropper-container {
+ direction: ltr;
+ font-size: 0;
+ line-height: 0;
+ position: relative;
+ touch-action: none;
+ user-select: none;
+
+ & img {
+ /* Avoid margin top issue (Occur only when margin-top <= -height) */
+ display: block;
+ height: 100%;
+ image-orientation: 0deg;
+ max-height: none !important;
+ max-width: none !important;
+ min-height: 0 !important;
+ min-width: 0 !important;
+ width: 100%;
+ }
+}
+
+.cropper-wrap-box,
+.cropper-canvas,
+.cropper-drag-box,
+.cropper-crop-box,
+.cropper-modal {
+ bottom: 0;
+ left: 0;
+ position: absolute;
+ right: 0;
+ top: 0;
+}
+
+.cropper-wrap-box,
+.cropper-canvas {
+ overflow: hidden;
+}
+
+.cropper-drag-box {
+ background-color: #fff;
+ opacity: 0;
+}
+
+.cropper-modal {
+ background-color: #000;
+ opacity: .5;
+}
+
+.cropper-view-box {
+ display: block;
+ height: 100%;
+ outline-color: color(var(--blue) alpha(75%));
+ outline: 1px solid var(--blue);
+ overflow: hidden;
+ width: 100%;
+}
+
+.cropper-dashed {
+ border: 0 dashed #eee;
+ display: block;
+ opacity: .5;
+ position: absolute;
+
+ &.dashed-h {
+ border-bottom-width: 1px;
+ border-top-width: 1px;
+ height: calc(100 / 3)%;
+ left: 0;
+ top: calc(100 / 3)%;
+ width: 100%;
+ }
+
+ &.dashed-v {
+ border-left-width: 1px;
+ border-right-width: 1px;
+ height: 100%;
+ left: calc(100 / 3)%;
+ top: 0;
+ width: calc(100 / 3)%;
+ }
+}
+
+.cropper-center {
+ display: block;
+ height: 0;
+ left: 50%;
+ opacity: .75;
+ position: absolute;
+ top: 50%;
+ width: 0;
+
+ &:before,
+ &:after {
+ background-color: #eee;
+ content: ' ';
+ display: block;
+ position: absolute;
+ }
+
+ &:before {
+ height: 1px;
+ left: -3px;
+ top: 0;
+ width: 7px;
+ }
+
+ &:after {
+ height: 7px;
+ left: 0;
+ top: -3px;
+ width: 1px;
+ }
+}
+
+.cropper-face,
+.cropper-line,
+.cropper-point {
+ display: block;
+ height: 100%;
+ opacity: .1;
+ position: absolute;
+ width: 100%;
+}
+
+.cropper-face {
+ background-color: #fff;
+ left: 0;
+ top: 0;
+}
+
+.cropper-line {
+ background-color: var(--blue);
+
+ &.line-e {
+ cursor: ew-resize;
+ right: -3px;
+ top: 0;
+ width: 5px;
+ }
+
+ &.line-n {
+ cursor: ns-resize;
+ height: 5px;
+ left: 0;
+ top: -3px;
+ }
+
+ &.line-w {
+ cursor: ew-resize;
+ left: -3px;
+ top: 0;
+ width: 5px;
+ }
+
+ &.line-s {
+ bottom: -3px;
+ cursor: ns-resize;
+ height: 5px;
+ left: 0;
+ }
+}
+
+.cropper-point {
+ background-color: var(--blue);
+ height: 5px;
+ opacity: .75;
+ width: 5px;
+
+ &.point-e {
+ cursor: ew-resize;
+ margin-top: -3px;
+ right: -3px;
+ top: 50%;
+ }
+
+ &.point-n {
+ cursor: ns-resize;
+ left: 50%;
+ margin-left: -3px;
+ top: -3px;
+ }
+
+ &.point-w {
+ cursor: ew-resize;
+ left: -3px;
+ margin-top: -3px;
+ top: 50%;
+ }
+
+ &.point-s {
+ bottom: -3px;
+ cursor: s-resize;
+ left: 50%;
+ margin-left: -3px;
+ }
+
+ &.point-ne {
+ cursor: nesw-resize;
+ right: -3px;
+ top: -3px;
+ }
+
+ &.point-nw {
+ cursor: nwse-resize;
+ left: -3px;
+ top: -3px;
+ }
+
+ &.point-sw {
+ bottom: -3px;
+ cursor: nesw-resize;
+ left: -3px;
+ }
+
+ &.point-se {
+ bottom: -3px;
+ cursor: nwse-resize;
+ height: 20px;
+ opacity: 1;
+ right: -3px;
+ width: 20px;
+
+ @media (min-width: 768px) {
+ height: 15px;
+ width: 15px;
+ }
+
+ @media (min-width: 992px) {
+ height: 10px;
+ width: 10px;
+ }
+
+ @media (min-width: 1200px) {
+ height: 5px;
+ opacity: .75;
+ width: 5px;
+ }
+ }
+
+ &.point-se:before {
+ background-color: var(--blue);
+ bottom: -50%;
+ content: ' ';
+ display: block;
+ height: 200%;
+ opacity: 0;
+ position: absolute;
+ right: -50%;
+ width: 200%;
+ }
+}
+
+.cropper-invisible {
+ opacity: 0;
+}
+
+.cropper-bg {
+ background-image: url('../images/bg.png');
+}
+
+.cropper-hide {
+ display: block;
+ height: 0;
+ position: absolute;
+ width: 0;
+}
+
+.cropper-hidden {
+ display: none !important;
+}
+
+.cropper-move {
+ cursor: move;
+}
+
+.cropper-crop {
+ cursor: crosshair;
+}
+
+.cropper-disabled .cropper-drag-box,
+.cropper-disabled .cropper-face,
+.cropper-disabled .cropper-line,
+.cropper-disabled .cropper-point {
+ cursor: not-allowed;
+}
+
diff --git a/library/cropperjs/src/images/bg.png b/library/cropperjs/src/images/bg.png
new file mode 100644
index 000000000..3c7056b19
Binary files /dev/null and b/library/cropperjs/src/images/bg.png differ
diff --git a/library/cropperjs/src/js/change.js b/library/cropperjs/src/js/change.js
new file mode 100644
index 000000000..014222ef0
--- /dev/null
+++ b/library/cropperjs/src/js/change.js
@@ -0,0 +1,471 @@
+import {
+ ACTION_ALL,
+ ACTION_CROP,
+ ACTION_EAST,
+ ACTION_MOVE,
+ ACTION_NORTH,
+ ACTION_NORTH_EAST,
+ ACTION_NORTH_WEST,
+ ACTION_SOUTH,
+ ACTION_SOUTH_EAST,
+ ACTION_SOUTH_WEST,
+ ACTION_WEST,
+ ACTION_ZOOM,
+ CLASS_HIDDEN,
+} from './constants';
+import {
+ each,
+ getMaxZoomRatio,
+ getOffset,
+ removeClass,
+} from './utilities';
+
+export default {
+ change(e) {
+ const {
+ options,
+ canvasData,
+ containerData,
+ cropBoxData,
+ pointers,
+ } = this;
+ let { action } = this;
+ let { aspectRatio } = options;
+ let {
+ left,
+ top,
+ width,
+ height,
+ } = cropBoxData;
+ const right = left + width;
+ const bottom = top + height;
+ let minLeft = 0;
+ let minTop = 0;
+ let maxWidth = containerData.width;
+ let maxHeight = containerData.height;
+ let renderable = true;
+ let offset;
+
+ // Locking aspect ratio in "free mode" by holding shift key
+ if (!aspectRatio && e.shiftKey) {
+ aspectRatio = width && height ? width / height : 1;
+ }
+
+ if (this.limited) {
+ ({ minLeft, minTop } = cropBoxData);
+ maxWidth = minLeft + Math.min(
+ containerData.width,
+ canvasData.width,
+ canvasData.left + canvasData.width,
+ );
+ maxHeight = minTop + Math.min(
+ containerData.height,
+ canvasData.height,
+ canvasData.top + canvasData.height,
+ );
+ }
+
+ const pointer = pointers[Object.keys(pointers)[0]];
+ const range = {
+ x: pointer.endX - pointer.startX,
+ y: pointer.endY - pointer.startY,
+ };
+ const check = (side) => {
+ switch (side) {
+ case ACTION_EAST:
+ if (right + range.x > maxWidth) {
+ range.x = maxWidth - right;
+ }
+
+ break;
+
+ case ACTION_WEST:
+ if (left + range.x < minLeft) {
+ range.x = minLeft - left;
+ }
+
+ break;
+
+ case ACTION_NORTH:
+ if (top + range.y < minTop) {
+ range.y = minTop - top;
+ }
+
+ break;
+
+ case ACTION_SOUTH:
+ if (bottom + range.y > maxHeight) {
+ range.y = maxHeight - bottom;
+ }
+
+ break;
+
+ default:
+ }
+ };
+
+ switch (action) {
+ // Move crop box
+ case ACTION_ALL:
+ left += range.x;
+ top += range.y;
+ break;
+
+ // Resize crop box
+ case ACTION_EAST:
+ if (range.x >= 0 && (right >= maxWidth || (aspectRatio &&
+ (top <= minTop || bottom >= maxHeight)))) {
+ renderable = false;
+ break;
+ }
+
+ check(ACTION_EAST);
+ width += range.x;
+
+ if (aspectRatio) {
+ height = width / aspectRatio;
+ top -= (range.x / aspectRatio) / 2;
+ }
+
+ if (width < 0) {
+ action = ACTION_WEST;
+ width = 0;
+ }
+
+ break;
+
+ case ACTION_NORTH:
+ if (range.y <= 0 && (top <= minTop || (aspectRatio &&
+ (left <= minLeft || right >= maxWidth)))) {
+ renderable = false;
+ break;
+ }
+
+ check(ACTION_NORTH);
+ height -= range.y;
+ top += range.y;
+
+ if (aspectRatio) {
+ width = height * aspectRatio;
+ left += (range.y * aspectRatio) / 2;
+ }
+
+ if (height < 0) {
+ action = ACTION_SOUTH;
+ height = 0;
+ }
+
+ break;
+
+ case ACTION_WEST:
+ if (range.x <= 0 && (left <= minLeft || (aspectRatio &&
+ (top <= minTop || bottom >= maxHeight)))) {
+ renderable = false;
+ break;
+ }
+
+ check(ACTION_WEST);
+ width -= range.x;
+ left += range.x;
+
+ if (aspectRatio) {
+ height = width / aspectRatio;
+ top += (range.x / aspectRatio) / 2;
+ }
+
+ if (width < 0) {
+ action = ACTION_EAST;
+ width = 0;
+ }
+
+ break;
+
+ case ACTION_SOUTH:
+ if (range.y >= 0 && (bottom >= maxHeight || (aspectRatio &&
+ (left <= minLeft || right >= maxWidth)))) {
+ renderable = false;
+ break;
+ }
+
+ check(ACTION_SOUTH);
+ height += range.y;
+
+ if (aspectRatio) {
+ width = height * aspectRatio;
+ left -= (range.y * aspectRatio) / 2;
+ }
+
+ if (height < 0) {
+ action = ACTION_NORTH;
+ height = 0;
+ }
+
+ break;
+
+ case ACTION_NORTH_EAST:
+ if (aspectRatio) {
+ if (range.y <= 0 && (top <= minTop || right >= maxWidth)) {
+ renderable = false;
+ break;
+ }
+
+ check(ACTION_NORTH);
+ height -= range.y;
+ top += range.y;
+ width = height * aspectRatio;
+ } else {
+ check(ACTION_NORTH);
+ check(ACTION_EAST);
+
+ if (range.x >= 0) {
+ if (right < maxWidth) {
+ width += range.x;
+ } else if (range.y <= 0 && top <= minTop) {
+ renderable = false;
+ }
+ } else {
+ width += range.x;
+ }
+
+ if (range.y <= 0) {
+ if (top > minTop) {
+ height -= range.y;
+ top += range.y;
+ }
+ } else {
+ height -= range.y;
+ top += range.y;
+ }
+ }
+
+ if (width < 0 && height < 0) {
+ action = ACTION_SOUTH_WEST;
+ height = 0;
+ width = 0;
+ } else if (width < 0) {
+ action = ACTION_NORTH_WEST;
+ width = 0;
+ } else if (height < 0) {
+ action = ACTION_SOUTH_EAST;
+ height = 0;
+ }
+
+ break;
+
+ case ACTION_NORTH_WEST:
+ if (aspectRatio) {
+ if (range.y <= 0 && (top <= minTop || left <= minLeft)) {
+ renderable = false;
+ break;
+ }
+
+ check(ACTION_NORTH);
+ height -= range.y;
+ top += range.y;
+ width = height * aspectRatio;
+ left += range.y * aspectRatio;
+ } else {
+ check(ACTION_NORTH);
+ check(ACTION_WEST);
+
+ if (range.x <= 0) {
+ if (left > minLeft) {
+ width -= range.x;
+ left += range.x;
+ } else if (range.y <= 0 && top <= minTop) {
+ renderable = false;
+ }
+ } else {
+ width -= range.x;
+ left += range.x;
+ }
+
+ if (range.y <= 0) {
+ if (top > minTop) {
+ height -= range.y;
+ top += range.y;
+ }
+ } else {
+ height -= range.y;
+ top += range.y;
+ }
+ }
+
+ if (width < 0 && height < 0) {
+ action = ACTION_SOUTH_EAST;
+ height = 0;
+ width = 0;
+ } else if (width < 0) {
+ action = ACTION_NORTH_EAST;
+ width = 0;
+ } else if (height < 0) {
+ action = ACTION_SOUTH_WEST;
+ height = 0;
+ }
+
+ break;
+
+ case ACTION_SOUTH_WEST:
+ if (aspectRatio) {
+ if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) {
+ renderable = false;
+ break;
+ }
+
+ check(ACTION_WEST);
+ width -= range.x;
+ left += range.x;
+ height = width / aspectRatio;
+ } else {
+ check(ACTION_SOUTH);
+ check(ACTION_WEST);
+
+ if (range.x <= 0) {
+ if (left > minLeft) {
+ width -= range.x;
+ left += range.x;
+ } else if (range.y >= 0 && bottom >= maxHeight) {
+ renderable = false;
+ }
+ } else {
+ width -= range.x;
+ left += range.x;
+ }
+
+ if (range.y >= 0) {
+ if (bottom < maxHeight) {
+ height += range.y;
+ }
+ } else {
+ height += range.y;
+ }
+ }
+
+ if (width < 0 && height < 0) {
+ action = ACTION_NORTH_EAST;
+ height = 0;
+ width = 0;
+ } else if (width < 0) {
+ action = ACTION_SOUTH_EAST;
+ width = 0;
+ } else if (height < 0) {
+ action = ACTION_NORTH_WEST;
+ height = 0;
+ }
+
+ break;
+
+ case ACTION_SOUTH_EAST:
+ if (aspectRatio) {
+ if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) {
+ renderable = false;
+ break;
+ }
+
+ check(ACTION_EAST);
+ width += range.x;
+ height = width / aspectRatio;
+ } else {
+ check(ACTION_SOUTH);
+ check(ACTION_EAST);
+
+ if (range.x >= 0) {
+ if (right < maxWidth) {
+ width += range.x;
+ } else if (range.y >= 0 && bottom >= maxHeight) {
+ renderable = false;
+ }
+ } else {
+ width += range.x;
+ }
+
+ if (range.y >= 0) {
+ if (bottom < maxHeight) {
+ height += range.y;
+ }
+ } else {
+ height += range.y;
+ }
+ }
+
+ if (width < 0 && height < 0) {
+ action = ACTION_NORTH_WEST;
+ height = 0;
+ width = 0;
+ } else if (width < 0) {
+ action = ACTION_SOUTH_WEST;
+ width = 0;
+ } else if (height < 0) {
+ action = ACTION_NORTH_EAST;
+ height = 0;
+ }
+
+ break;
+
+ // Move canvas
+ case ACTION_MOVE:
+ this.move(range.x, range.y);
+ renderable = false;
+ break;
+
+ // Zoom canvas
+ case ACTION_ZOOM:
+ this.zoom(getMaxZoomRatio(pointers), e);
+ renderable = false;
+ break;
+
+ // Create crop box
+ case ACTION_CROP:
+ if (!range.x || !range.y) {
+ renderable = false;
+ break;
+ }
+
+ offset = getOffset(this.cropper);
+ left = pointer.startX - offset.left;
+ top = pointer.startY - offset.top;
+ width = cropBoxData.minWidth;
+ height = cropBoxData.minHeight;
+
+ if (range.x > 0) {
+ action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST;
+ } else if (range.x < 0) {
+ left -= width;
+ action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST;
+ }
+
+ if (range.y < 0) {
+ top -= height;
+ }
+
+ // Show the crop box if is hidden
+ if (!this.cropped) {
+ removeClass(this.cropBox, CLASS_HIDDEN);
+ this.cropped = true;
+
+ if (this.limited) {
+ this.limitCropBox(true, true);
+ }
+ }
+
+ break;
+
+ default:
+ }
+
+ if (renderable) {
+ cropBoxData.width = width;
+ cropBoxData.height = height;
+ cropBoxData.left = left;
+ cropBoxData.top = top;
+ this.action = action;
+ this.renderCropBox();
+ }
+
+ // Override
+ each(pointers, (p) => {
+ p.startX = p.endX;
+ p.startY = p.endY;
+ });
+ },
+};
diff --git a/library/cropperjs/src/js/constants.js b/library/cropperjs/src/js/constants.js
new file mode 100644
index 000000000..c675d4d1c
--- /dev/null
+++ b/library/cropperjs/src/js/constants.js
@@ -0,0 +1,56 @@
+export const WINDOW = typeof window !== 'undefined' ? window : {};
+export const NAMESPACE = 'cropper';
+
+// Actions
+export const ACTION_ALL = 'all';
+export const ACTION_CROP = 'crop';
+export const ACTION_MOVE = 'move';
+export const ACTION_ZOOM = 'zoom';
+export const ACTION_EAST = 'e';
+export const ACTION_WEST = 'w';
+export const ACTION_SOUTH = 's';
+export const ACTION_NORTH = 'n';
+export const ACTION_NORTH_EAST = 'ne';
+export const ACTION_NORTH_WEST = 'nw';
+export const ACTION_SOUTH_EAST = 'se';
+export const ACTION_SOUTH_WEST = 'sw';
+
+// Classes
+export const CLASS_CROP = `${NAMESPACE}-crop`;
+export const CLASS_DISABLED = `${NAMESPACE}-disabled`;
+export const CLASS_HIDDEN = `${NAMESPACE}-hidden`;
+export const CLASS_HIDE = `${NAMESPACE}-hide`;
+export const CLASS_INVISIBLE = `${NAMESPACE}-invisible`;
+export const CLASS_MODAL = `${NAMESPACE}-modal`;
+export const CLASS_MOVE = `${NAMESPACE}-move`;
+
+// Data keys
+export const DATA_ACTION = 'action';
+export const DATA_PREVIEW = 'preview';
+
+// Drag modes
+export const DRAG_MODE_CROP = 'crop';
+export const DRAG_MODE_MOVE = 'move';
+export const DRAG_MODE_NONE = 'none';
+
+// Events
+export const EVENT_CROP = 'crop';
+export const EVENT_CROP_END = 'cropend';
+export const EVENT_CROP_MOVE = 'cropmove';
+export const EVENT_CROP_START = 'cropstart';
+export const EVENT_DBLCLICK = 'dblclick';
+export const EVENT_ERROR = 'error';
+export const EVENT_LOAD = 'load';
+export const EVENT_POINTER_DOWN = WINDOW.PointerEvent ? 'pointerdown' : 'touchstart mousedown';
+export const EVENT_POINTER_MOVE = WINDOW.PointerEvent ? 'pointermove' : 'touchmove mousemove';
+export const EVENT_POINTER_UP = WINDOW.PointerEvent ? 'pointerup pointercancel' : 'touchend touchcancel mouseup';
+export const EVENT_READY = 'ready';
+export const EVENT_RESIZE = 'resize';
+export const EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll';
+export const EVENT_ZOOM = 'zoom';
+
+// RegExps
+export const REGEXP_ACTIONS = /^(?:e|w|s|n|se|sw|ne|nw|all|crop|move|zoom)$/;
+export const REGEXP_DATA_URL = /^data:/;
+export const REGEXP_DATA_URL_JPEG = /^data:image\/jpeg;base64,/;
+export const REGEXP_TAG_NAME = /^(?:img|canvas)$/i;
diff --git a/library/cropperjs/src/js/cropper.js b/library/cropperjs/src/js/cropper.js
new file mode 100644
index 000000000..97f3511df
--- /dev/null
+++ b/library/cropperjs/src/js/cropper.js
@@ -0,0 +1,421 @@
+import DEFAULTS from './defaults';
+import TEMPLATE from './template';
+import render from './render';
+import preview from './preview';
+import events from './events';
+import handlers from './handlers';
+import change from './change';
+import methods from './methods';
+import {
+ ACTION_ALL,
+ CLASS_HIDDEN,
+ CLASS_HIDE,
+ CLASS_INVISIBLE,
+ CLASS_MODAL,
+ CLASS_MOVE,
+ DATA_ACTION,
+ EVENT_CROP,
+ EVENT_ERROR,
+ EVENT_LOAD,
+ EVENT_READY,
+ NAMESPACE,
+ REGEXP_DATA_URL,
+ REGEXP_DATA_URL_JPEG,
+ REGEXP_TAG_NAME,
+ WINDOW,
+} from './constants';
+import {
+ addClass,
+ addListener,
+ addTimestamp,
+ arrayBufferToDataURL,
+ dataURLToArrayBuffer,
+ dispatchEvent,
+ extend,
+ getData,
+ getImageNaturalSizes,
+ getOrientation,
+ isCrossOriginURL,
+ isFunction,
+ isPlainObject,
+ parseOrientation,
+ proxy,
+ removeClass,
+ removeListener,
+ setData,
+} from './utilities';
+
+const AnotherCropper = WINDOW.Cropper;
+
+class Cropper {
+ /**
+ * Create a new Cropper.
+ * @param {Element} element - The target element for cropping.
+ * @param {Object} [options={}] - The configuration options.
+ */
+ constructor(element, options = {}) {
+ if (!element || !REGEXP_TAG_NAME.test(element.tagName)) {
+ throw new Error('The first argument is required and must be an or element.');
+ }
+
+ this.element = element;
+ this.options = extend({}, DEFAULTS, isPlainObject(options) && options);
+ this.complete = false;
+ this.cropped = false;
+ this.disabled = false;
+ this.isImg = false;
+ this.limited = false;
+ this.loaded = false;
+ this.ready = false;
+ this.replaced = false;
+ this.wheeling = false;
+ this.originalUrl = '';
+ this.canvasData = null;
+ this.cropBoxData = null;
+ this.previews = null;
+ this.pointers = {};
+ this.init();
+ }
+
+ init() {
+ const { element } = this;
+ const tagName = element.tagName.toLowerCase();
+ let url;
+
+ if (getData(element, NAMESPACE)) {
+ return;
+ }
+
+ setData(element, NAMESPACE, this);
+
+ if (tagName === 'img') {
+ this.isImg = true;
+
+ // e.g.: "img/picture.jpg"
+ url = element.getAttribute('src') || '';
+ this.originalUrl = url;
+
+ // Stop when it's a blank image
+ if (!url) {
+ return;
+ }
+
+ // e.g.: "http://example.com/img/picture.jpg"
+ url = element.src;
+ } else if (tagName === 'canvas' && window.HTMLCanvasElement) {
+ url = element.toDataURL();
+ }
+
+ this.load(url);
+ }
+
+ load(url) {
+ if (!url) {
+ return;
+ }
+
+ this.url = url;
+ this.imageData = {};
+
+ const { element, options } = this;
+
+ if (!options.checkOrientation || !window.ArrayBuffer) {
+ this.clone();
+ return;
+ }
+
+ // XMLHttpRequest disallows to open a Data URL in some browsers like IE11 and Safari
+ if (REGEXP_DATA_URL.test(url)) {
+ if (REGEXP_DATA_URL_JPEG.test(url)) {
+ this.read(dataURLToArrayBuffer(url));
+ } else {
+ this.clone();
+ }
+
+ return;
+ }
+
+ const xhr = new XMLHttpRequest();
+
+ xhr.onerror = () => {
+ this.clone();
+ };
+
+ xhr.onload = () => {
+ this.read(xhr.response);
+ };
+
+ // Bust cache when there is a "crossOrigin" property
+ if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) {
+ url = addTimestamp(url);
+ }
+
+ xhr.open('get', url);
+ xhr.responseType = 'arraybuffer';
+ xhr.withCredentials = element.crossOrigin === 'use-credentials';
+ xhr.send();
+ }
+
+ read(arrayBuffer) {
+ const { options, imageData } = this;
+ const orientation = getOrientation(arrayBuffer);
+ let rotate = 0;
+ let scaleX = 1;
+ let scaleY = 1;
+
+ if (orientation > 1) {
+ this.url = arrayBufferToDataURL(arrayBuffer, 'image/jpeg');
+ ({ rotate, scaleX, scaleY } = parseOrientation(orientation));
+ }
+
+ if (options.rotatable) {
+ imageData.rotate = rotate;
+ }
+
+ if (options.scalable) {
+ imageData.scaleX = scaleX;
+ imageData.scaleY = scaleY;
+ }
+
+ this.clone();
+ }
+
+ clone() {
+ const { element, url } = this;
+ let crossOrigin;
+ let crossOriginUrl;
+
+ if (this.options.checkCrossOrigin && isCrossOriginURL(url)) {
+ ({ crossOrigin } = element);
+
+ if (crossOrigin) {
+ crossOriginUrl = url;
+ } else {
+ crossOrigin = 'anonymous';
+
+ // Bust cache when there is not a "crossOrigin" property
+ crossOriginUrl = addTimestamp(url);
+ }
+ }
+
+ this.crossOrigin = crossOrigin;
+ this.crossOriginUrl = crossOriginUrl;
+
+ const image = document.createElement('img');
+
+ if (crossOrigin) {
+ image.crossOrigin = crossOrigin;
+ }
+
+ image.src = crossOriginUrl || url;
+
+ const start = proxy(this.start, this);
+ const stop = proxy(this.stop, this);
+
+ this.image = image;
+ this.onStart = start;
+ this.onStop = stop;
+
+ if (this.isImg) {
+ if (element.complete) {
+ this.start();
+ } else {
+ addListener(element, EVENT_LOAD, start);
+ }
+ } else {
+ addListener(image, EVENT_LOAD, start);
+ addListener(image, EVENT_ERROR, stop);
+ addClass(image, CLASS_HIDE);
+ element.parentNode.insertBefore(image, element.nextSibling);
+ }
+ }
+
+ start(event) {
+ const image = this.isImg ? this.element : this.image;
+
+ if (event) {
+ removeListener(image, EVENT_LOAD, this.onStart);
+ removeListener(image, EVENT_ERROR, this.onStop);
+ }
+
+ getImageNaturalSizes(image, (naturalWidth, naturalHeight) => {
+ extend(this.imageData, {
+ naturalWidth,
+ naturalHeight,
+ aspectRatio: naturalWidth / naturalHeight,
+ });
+ this.loaded = true;
+ this.build();
+ });
+ }
+
+ stop() {
+ const { image } = this;
+
+ removeListener(image, EVENT_LOAD, this.onStart);
+ removeListener(image, EVENT_ERROR, this.onStop);
+ image.parentNode.removeChild(image);
+ this.image = null;
+ }
+
+ build() {
+ if (!this.loaded) {
+ return;
+ }
+
+ // Unbuild first when replace
+ if (this.ready) {
+ this.unbuild();
+ }
+
+ const { element, options, image } = this;
+
+ // Create cropper elements
+ const container = element.parentNode;
+ const template = document.createElement('div');
+
+ template.innerHTML = TEMPLATE;
+
+ const cropper = template.querySelector(`.${NAMESPACE}-container`);
+ const canvas = cropper.querySelector(`.${NAMESPACE}-canvas`);
+ const dragBox = cropper.querySelector(`.${NAMESPACE}-drag-box`);
+ const cropBox = cropper.querySelector(`.${NAMESPACE}-crop-box`);
+ const face = cropBox.querySelector(`.${NAMESPACE}-face`);
+
+ this.container = container;
+ this.cropper = cropper;
+ this.canvas = canvas;
+ this.dragBox = dragBox;
+ this.cropBox = cropBox;
+ this.viewBox = cropper.querySelector(`.${NAMESPACE}-view-box`);
+ this.face = face;
+
+ canvas.appendChild(image);
+
+ // Hide the original image
+ addClass(element, CLASS_HIDDEN);
+
+ // Inserts the cropper after to the current image
+ container.insertBefore(cropper, element.nextSibling);
+
+ // Show the image if is hidden
+ if (!this.isImg) {
+ removeClass(image, CLASS_HIDE);
+ }
+
+ this.initPreview();
+ this.bind();
+
+ options.aspectRatio = Math.max(0, options.aspectRatio) || NaN;
+ options.viewMode = Math.max(0, Math.min(3, Math.round(options.viewMode))) || 0;
+
+ this.cropped = options.autoCrop;
+
+ if (options.autoCrop) {
+ if (options.modal) {
+ addClass(dragBox, CLASS_MODAL);
+ }
+ } else {
+ addClass(cropBox, CLASS_HIDDEN);
+ }
+
+ if (!options.guides) {
+ addClass(cropBox.getElementsByClassName(`${NAMESPACE}-dashed`), CLASS_HIDDEN);
+ }
+
+ if (!options.center) {
+ addClass(cropBox.getElementsByClassName(`${NAMESPACE}-center`), CLASS_HIDDEN);
+ }
+
+ if (options.background) {
+ addClass(cropper, `${NAMESPACE}-bg`);
+ }
+
+ if (!options.highlight) {
+ addClass(face, CLASS_INVISIBLE);
+ }
+
+ if (options.cropBoxMovable) {
+ addClass(face, CLASS_MOVE);
+ setData(face, DATA_ACTION, ACTION_ALL);
+ }
+
+ if (!options.cropBoxResizable) {
+ addClass(cropBox.getElementsByClassName(`${NAMESPACE}-line`), CLASS_HIDDEN);
+ addClass(cropBox.getElementsByClassName(`${NAMESPACE}-point`), CLASS_HIDDEN);
+ }
+
+ this.setDragMode(options.dragMode);
+ this.render();
+ this.ready = true;
+ this.setData(options.data);
+
+ // Call the "ready" option asynchronously to keep "image.cropper" is defined
+ this.completing = setTimeout(() => {
+ if (isFunction(options.ready)) {
+ addListener(element, EVENT_READY, options.ready, {
+ once: true,
+ });
+ }
+
+ dispatchEvent(element, EVENT_READY);
+ dispatchEvent(element, EVENT_CROP, this.getData());
+
+ this.complete = true;
+ }, 0);
+ }
+
+ unbuild() {
+ if (!this.ready) {
+ return;
+ }
+
+ if (!this.complete) {
+ clearTimeout(this.completing);
+ }
+
+ this.ready = false;
+ this.complete = false;
+ this.initialImageData = null;
+
+ // Clear `initialCanvasData` is necessary when replace
+ this.initialCanvasData = null;
+ this.initialCropBoxData = null;
+ this.containerData = null;
+ this.canvasData = null;
+
+ // Clear `cropBoxData` is necessary when replace
+ this.cropBoxData = null;
+ this.unbind();
+ this.resetPreview();
+ this.previews = null;
+ this.viewBox = null;
+ this.cropBox = null;
+ this.dragBox = null;
+ this.canvas = null;
+ this.container = null;
+ this.cropper.parentNode.removeChild(this.cropper);
+ this.cropper = null;
+ }
+
+ /**
+ * Get the no conflict cropper class.
+ * @returns {Cropper} The cropper class.
+ */
+ static noConflict() {
+ window.Cropper = AnotherCropper;
+ return Cropper;
+ }
+
+ /**
+ * Change the default options.
+ * @param {Object} options - The new default options.
+ */
+ static setDefaults(options) {
+ extend(DEFAULTS, isPlainObject(options) && options);
+ }
+}
+
+extend(Cropper.prototype, render, preview, events, handlers, change, methods);
+
+export default Cropper;
diff --git a/library/cropperjs/src/js/defaults.js b/library/cropperjs/src/js/defaults.js
new file mode 100644
index 000000000..aa469e73a
--- /dev/null
+++ b/library/cropperjs/src/js/defaults.js
@@ -0,0 +1,99 @@
+import {
+ DRAG_MODE_CROP,
+} from './constants';
+
+export default {
+ // Define the view mode of the cropper
+ viewMode: 0, // 0, 1, 2, 3
+
+ // Define the dragging mode of the cropper
+ dragMode: DRAG_MODE_CROP, // 'crop', 'move' or 'none'
+
+ // Define the aspect ratio of the crop box
+ aspectRatio: NaN,
+
+ // An object with the previous cropping result data
+ data: null,
+
+ // A selector for adding extra containers to preview
+ preview: '',
+
+ // Re-render the cropper when resize the window
+ responsive: true,
+
+ // Restore the cropped area after resize the window
+ restore: true,
+
+ // Check if the current image is a cross-origin image
+ checkCrossOrigin: true,
+
+ // Check the current image's Exif Orientation information
+ checkOrientation: true,
+
+ // Show the black modal
+ modal: true,
+
+ // Show the dashed lines for guiding
+ guides: true,
+
+ // Show the center indicator for guiding
+ center: true,
+
+ // Show the white modal to highlight the crop box
+ highlight: true,
+
+ // Show the grid background
+ background: true,
+
+ // Enable to crop the image automatically when initialize
+ autoCrop: true,
+
+ // Define the percentage of automatic cropping area when initializes
+ autoCropArea: 0.8,
+
+ // Enable to move the image
+ movable: true,
+
+ // Enable to rotate the image
+ rotatable: true,
+
+ // Enable to scale the image
+ scalable: true,
+
+ // Enable to zoom the image
+ zoomable: true,
+
+ // Enable to zoom the image by dragging touch
+ zoomOnTouch: true,
+
+ // Enable to zoom the image by wheeling mouse
+ zoomOnWheel: true,
+
+ // Define zoom ratio when zoom the image by wheeling mouse
+ wheelZoomRatio: 0.1,
+
+ // Enable to move the crop box
+ cropBoxMovable: true,
+
+ // Enable to resize the crop box
+ cropBoxResizable: true,
+
+ // Toggle drag mode between "crop" and "move" when click twice on the cropper
+ toggleDragModeOnDblclick: true,
+
+ // Size limitation
+ minCanvasWidth: 0,
+ minCanvasHeight: 0,
+ minCropBoxWidth: 0,
+ minCropBoxHeight: 0,
+ minContainerWidth: 200,
+ minContainerHeight: 100,
+
+ // Shortcuts of events
+ ready: null,
+ cropstart: null,
+ cropmove: null,
+ cropend: null,
+ crop: null,
+ zoom: null,
+};
diff --git a/library/cropperjs/src/js/events.js b/library/cropperjs/src/js/events.js
new file mode 100644
index 000000000..3753db022
--- /dev/null
+++ b/library/cropperjs/src/js/events.js
@@ -0,0 +1,111 @@
+import {
+ EVENT_CROP,
+ EVENT_CROP_END,
+ EVENT_CROP_MOVE,
+ EVENT_CROP_START,
+ EVENT_DBLCLICK,
+ EVENT_POINTER_DOWN,
+ EVENT_POINTER_MOVE,
+ EVENT_POINTER_UP,
+ EVENT_RESIZE,
+ EVENT_WHEEL,
+ EVENT_ZOOM,
+} from './constants';
+import {
+ addListener,
+ isFunction,
+ proxy,
+ removeListener,
+} from './utilities';
+
+export default {
+ bind() {
+ const { element, options, cropper } = this;
+
+ if (isFunction(options.cropstart)) {
+ addListener(element, EVENT_CROP_START, options.cropstart);
+ }
+
+ if (isFunction(options.cropmove)) {
+ addListener(element, EVENT_CROP_MOVE, options.cropmove);
+ }
+
+ if (isFunction(options.cropend)) {
+ addListener(element, EVENT_CROP_END, options.cropend);
+ }
+
+ if (isFunction(options.crop)) {
+ addListener(element, EVENT_CROP, options.crop);
+ }
+
+ if (isFunction(options.zoom)) {
+ addListener(element, EVENT_ZOOM, options.zoom);
+ }
+
+ addListener(cropper, EVENT_POINTER_DOWN, (this.onCropStart = proxy(this.cropStart, this)));
+
+ if (options.zoomable && options.zoomOnWheel) {
+ addListener(cropper, EVENT_WHEEL, (this.onWheel = proxy(this.wheel, this)));
+ }
+
+ if (options.toggleDragModeOnDblclick) {
+ addListener(cropper, EVENT_DBLCLICK, (this.onDblclick = proxy(this.dblclick, this)));
+ }
+
+ addListener(
+ element.ownerDocument,
+ EVENT_POINTER_MOVE,
+ (this.onCropMove = proxy(this.cropMove, this)),
+ );
+ addListener(
+ element.ownerDocument,
+ EVENT_POINTER_UP,
+ (this.onCropEnd = proxy(this.cropEnd, this)),
+ );
+
+ if (options.responsive) {
+ addListener(window, EVENT_RESIZE, (this.onResize = proxy(this.resize, this)));
+ }
+ },
+
+ unbind() {
+ const { element, options, cropper } = this;
+
+ if (isFunction(options.cropstart)) {
+ removeListener(element, EVENT_CROP_START, options.cropstart);
+ }
+
+ if (isFunction(options.cropmove)) {
+ removeListener(element, EVENT_CROP_MOVE, options.cropmove);
+ }
+
+ if (isFunction(options.cropend)) {
+ removeListener(element, EVENT_CROP_END, options.cropend);
+ }
+
+ if (isFunction(options.crop)) {
+ removeListener(element, EVENT_CROP, options.crop);
+ }
+
+ if (isFunction(options.zoom)) {
+ removeListener(element, EVENT_ZOOM, options.zoom);
+ }
+
+ removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart);
+
+ if (options.zoomable && options.zoomOnWheel) {
+ removeListener(cropper, EVENT_WHEEL, this.onWheel);
+ }
+
+ if (options.toggleDragModeOnDblclick) {
+ removeListener(cropper, EVENT_DBLCLICK, this.onDblclick);
+ }
+
+ removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove);
+ removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd);
+
+ if (options.responsive) {
+ removeListener(window, EVENT_RESIZE, this.onResize);
+ }
+ },
+};
diff --git a/library/cropperjs/src/js/handlers.js b/library/cropperjs/src/js/handlers.js
new file mode 100644
index 000000000..7b7b2469a
--- /dev/null
+++ b/library/cropperjs/src/js/handlers.js
@@ -0,0 +1,212 @@
+import {
+ ACTION_CROP,
+ ACTION_ZOOM,
+ CLASS_CROP,
+ CLASS_MODAL,
+ DATA_ACTION,
+ DRAG_MODE_CROP,
+ DRAG_MODE_MOVE,
+ DRAG_MODE_NONE,
+ EVENT_CROP_END,
+ EVENT_CROP_MOVE,
+ EVENT_CROP_START,
+ REGEXP_ACTIONS,
+} from './constants';
+import {
+ addClass,
+ dispatchEvent,
+ each,
+ extend,
+ getData,
+ getPointer,
+ hasClass,
+ toggleClass,
+} from './utilities';
+
+export default {
+ resize() {
+ const { options, container, containerData } = this;
+ const minContainerWidth = Number(options.minContainerWidth) || 200;
+ const minContainerHeight = Number(options.minContainerHeight) || 100;
+
+ if (this.disabled || containerData.width <= minContainerWidth ||
+ containerData.height <= minContainerHeight) {
+ return;
+ }
+
+ const ratio = container.offsetWidth / containerData.width;
+
+ // Resize when width changed or height changed
+ if (ratio !== 1 || container.offsetHeight !== containerData.height) {
+ let canvasData;
+ let cropBoxData;
+
+ if (options.restore) {
+ canvasData = this.getCanvasData();
+ cropBoxData = this.getCropBoxData();
+ }
+
+ this.render();
+
+ if (options.restore) {
+ this.setCanvasData(each(canvasData, (n, i) => {
+ canvasData[i] = n * ratio;
+ }));
+ this.setCropBoxData(each(cropBoxData, (n, i) => {
+ cropBoxData[i] = n * ratio;
+ }));
+ }
+ }
+ },
+
+ dblclick() {
+ if (this.disabled || this.options.dragMode === DRAG_MODE_NONE) {
+ return;
+ }
+
+ this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP);
+ },
+
+ wheel(e) {
+ const ratio = Number(this.options.wheelZoomRatio) || 0.1;
+ let delta = 1;
+
+ if (this.disabled) {
+ return;
+ }
+
+ e.preventDefault();
+
+ // Limit wheel speed to prevent zoom too fast (#21)
+ if (this.wheeling) {
+ return;
+ }
+
+ this.wheeling = true;
+
+ setTimeout(() => {
+ this.wheeling = false;
+ }, 50);
+
+ if (e.deltaY) {
+ delta = e.deltaY > 0 ? 1 : -1;
+ } else if (e.wheelDelta) {
+ delta = -e.wheelDelta / 120;
+ } else if (e.detail) {
+ delta = e.detail > 0 ? 1 : -1;
+ }
+
+ this.zoom(-delta * ratio, e);
+ },
+
+ cropStart(e) {
+ if (this.disabled) {
+ return;
+ }
+
+ const { options, pointers } = this;
+ let action;
+
+ if (e.changedTouches) {
+ // Handle touch event
+ each(e.changedTouches, (touch) => {
+ pointers[touch.identifier] = getPointer(touch);
+ });
+ } else {
+ // Handle mouse event and pointer event
+ pointers[e.pointerId || 0] = getPointer(e);
+ }
+
+ if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) {
+ action = ACTION_ZOOM;
+ } else {
+ action = getData(e.target, DATA_ACTION);
+ }
+
+ if (!REGEXP_ACTIONS.test(action)) {
+ return;
+ }
+
+ if (dispatchEvent(this.element, EVENT_CROP_START, {
+ originalEvent: e,
+ action,
+ }) === false) {
+ return;
+ }
+
+ e.preventDefault();
+
+ this.action = action;
+ this.cropping = false;
+
+ if (action === ACTION_CROP) {
+ this.cropping = true;
+ addClass(this.dragBox, CLASS_MODAL);
+ }
+ },
+
+ cropMove(e) {
+ const { action } = this;
+
+ if (this.disabled || !action) {
+ return;
+ }
+
+ const { pointers } = this;
+
+ e.preventDefault();
+
+ if (dispatchEvent(this.element, EVENT_CROP_MOVE, {
+ originalEvent: e,
+ action,
+ }) === false) {
+ return;
+ }
+
+ if (e.changedTouches) {
+ each(e.changedTouches, (touch) => {
+ extend(pointers[touch.identifier], getPointer(touch, true));
+ });
+ } else {
+ extend(pointers[e.pointerId || 0], getPointer(e, true));
+ }
+
+ this.change(e);
+ },
+
+ cropEnd(e) {
+ if (this.disabled) {
+ return;
+ }
+
+ const { action, pointers } = this;
+
+ if (e.changedTouches) {
+ each(e.changedTouches, (touch) => {
+ delete pointers[touch.identifier];
+ });
+ } else {
+ delete pointers[e.pointerId || 0];
+ }
+
+ if (!action) {
+ return;
+ }
+
+ e.preventDefault();
+
+ if (!Object.keys(pointers).length) {
+ this.action = '';
+ }
+
+ if (this.cropping) {
+ this.cropping = false;
+ toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal);
+ }
+
+ dispatchEvent(this.element, EVENT_CROP_END, {
+ originalEvent: e,
+ action,
+ });
+ },
+};
diff --git a/library/cropperjs/src/js/methods.js b/library/cropperjs/src/js/methods.js
new file mode 100644
index 000000000..3627d2bd1
--- /dev/null
+++ b/library/cropperjs/src/js/methods.js
@@ -0,0 +1,842 @@
+import {
+ CLASS_CROP,
+ CLASS_DISABLED,
+ CLASS_HIDDEN,
+ CLASS_MODAL,
+ CLASS_MOVE,
+ DATA_ACTION,
+ DRAG_MODE_CROP,
+ DRAG_MODE_MOVE,
+ DRAG_MODE_NONE,
+ EVENT_LOAD,
+ EVENT_ZOOM,
+ NAMESPACE,
+} from './constants';
+import {
+ addClass,
+ dispatchEvent,
+ each,
+ extend,
+ getAdjustedSizes,
+ getOffset,
+ getPointersCenter,
+ getSourceCanvas,
+ isFunction,
+ isNumber,
+ isPlainObject,
+ isUndefined,
+ normalizeDecimalNumber,
+ removeClass,
+ removeData,
+ removeListener,
+ setData,
+ toggleClass,
+} from './utilities';
+
+export default {
+ // Show the crop box manually
+ crop() {
+ if (this.ready && !this.disabled) {
+ if (!this.cropped) {
+ this.cropped = true;
+ this.limitCropBox(true, true);
+
+ if (this.options.modal) {
+ addClass(this.dragBox, CLASS_MODAL);
+ }
+
+ removeClass(this.cropBox, CLASS_HIDDEN);
+ }
+
+ this.setCropBoxData(this.initialCropBoxData);
+ }
+
+ return this;
+ },
+
+ // Reset the image and crop box to their initial states
+ reset() {
+ if (this.ready && !this.disabled) {
+ this.imageData = extend({}, this.initialImageData);
+ this.canvasData = extend({}, this.initialCanvasData);
+ this.cropBoxData = extend({}, this.initialCropBoxData);
+ this.renderCanvas();
+
+ if (this.cropped) {
+ this.renderCropBox();
+ }
+ }
+
+ return this;
+ },
+
+ // Clear the crop box
+ clear() {
+ if (this.cropped && !this.disabled) {
+ extend(this.cropBoxData, {
+ left: 0,
+ top: 0,
+ width: 0,
+ height: 0,
+ });
+
+ this.cropped = false;
+ this.renderCropBox();
+ this.limitCanvas(true, true);
+
+ // Render canvas after crop box rendered
+ this.renderCanvas();
+ removeClass(this.dragBox, CLASS_MODAL);
+ addClass(this.cropBox, CLASS_HIDDEN);
+ }
+
+ return this;
+ },
+
+ /**
+ * Replace the image's src and rebuild the cropper
+ * @param {string} url - The new URL.
+ * @param {boolean} [onlyColorChanged] - Indicate if the new image only changed color.
+ * @returns {Object} this
+ */
+ replace(url, onlyColorChanged = false) {
+ if (!this.disabled && url) {
+ if (this.isImg) {
+ this.element.src = url;
+ }
+
+ if (onlyColorChanged) {
+ this.url = url;
+ this.image.src = url;
+
+ if (this.ready) {
+ this.image2.src = url;
+
+ each(this.previews, (element) => {
+ element.getElementsByTagName('img')[0].src = url;
+ });
+ }
+ } else {
+ if (this.isImg) {
+ this.replaced = true;
+ }
+
+ // Clear previous data
+ this.options.data = null;
+ this.load(url);
+ }
+ }
+
+ return this;
+ },
+
+ // Enable (unfreeze) the cropper
+ enable() {
+ if (this.ready) {
+ this.disabled = false;
+ removeClass(this.cropper, CLASS_DISABLED);
+ }
+
+ return this;
+ },
+
+ // Disable (freeze) the cropper
+ disable() {
+ if (this.ready) {
+ this.disabled = true;
+ addClass(this.cropper, CLASS_DISABLED);
+ }
+
+ return this;
+ },
+
+ // Destroy the cropper and remove the instance from the image
+ destroy() {
+ const { element, image } = this;
+
+ if (this.loaded) {
+ if (this.isImg && this.replaced) {
+ element.src = this.originalUrl;
+ }
+
+ this.unbuild();
+ removeClass(element, CLASS_HIDDEN);
+ } else if (this.isImg) {
+ removeListener(element, EVENT_LOAD, this.onStart);
+ } else if (image) {
+ image.parentNode.removeChild(image);
+ }
+
+ removeData(element, NAMESPACE);
+
+ return this;
+ },
+
+ /**
+ * Move the canvas with relative offsets
+ * @param {number} offsetX - The relative offset distance on the x-axis.
+ * @param {number} offsetY - The relative offset distance on the y-axis.
+ * @returns {Object} this
+ */
+ move(offsetX, offsetY) {
+ const { left, top } = this.canvasData;
+
+ return this.moveTo(
+ isUndefined(offsetX) ? offsetX : (left + Number(offsetX)),
+ isUndefined(offsetY) ? offsetY : (top + Number(offsetY)),
+ );
+ },
+
+ /**
+ * Move the canvas to an absolute point
+ * @param {number} x - The x-axis coordinate.
+ * @param {number} [y=x] - The y-axis coordinate.
+ * @returns {Object} this
+ */
+ moveTo(x, y = x) {
+ const { canvasData } = this;
+ let changed = false;
+
+ x = Number(x);
+ y = Number(y);
+
+ if (this.ready && !this.disabled && this.options.movable) {
+ if (isNumber(x)) {
+ canvasData.left = x;
+ changed = true;
+ }
+
+ if (isNumber(y)) {
+ canvasData.top = y;
+ changed = true;
+ }
+
+ if (changed) {
+ this.renderCanvas(true);
+ }
+ }
+
+ return this;
+ },
+
+ /**
+ * Zoom the canvas with a relative ratio
+ * @param {number} ratio - The target ratio.
+ * @param {Event} _originalEvent - The original event if any.
+ * @returns {Object} this
+ */
+ zoom(ratio, _originalEvent) {
+ const { canvasData } = this;
+
+ ratio = Number(ratio);
+
+ if (ratio < 0) {
+ ratio = 1 / (1 - ratio);
+ } else {
+ ratio = 1 + ratio;
+ }
+
+ return this.zoomTo((canvasData.width * ratio) / canvasData.naturalWidth, null, _originalEvent);
+ },
+
+ /**
+ * Zoom the canvas to an absolute ratio
+ * @param {number} ratio - The target ratio.
+ * @param {Object} pivot - The zoom pivot point coordinate.
+ * @param {Event} _originalEvent - The original event if any.
+ * @returns {Object} this
+ */
+ zoomTo(ratio, pivot, _originalEvent) {
+ const { options, canvasData } = this;
+ const {
+ width,
+ height,
+ naturalWidth,
+ naturalHeight,
+ } = canvasData;
+
+ ratio = Number(ratio);
+
+ if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) {
+ const newWidth = naturalWidth * ratio;
+ const newHeight = naturalHeight * ratio;
+
+ if (dispatchEvent(this.element, EVENT_ZOOM, {
+ originalEvent: _originalEvent,
+ oldRatio: width / naturalWidth,
+ ratio: newWidth / naturalWidth,
+ }) === false) {
+ return this;
+ }
+
+ if (_originalEvent) {
+ const { pointers } = this;
+ const offset = getOffset(this.cropper);
+ const center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : {
+ pageX: _originalEvent.pageX,
+ pageY: _originalEvent.pageY,
+ };
+
+ // Zoom from the triggering point of the event
+ canvasData.left -= (newWidth - width) * (
+ ((center.pageX - offset.left) - canvasData.left) / width
+ );
+ canvasData.top -= (newHeight - height) * (
+ ((center.pageY - offset.top) - canvasData.top) / height
+ );
+ } else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) {
+ canvasData.left -= (newWidth - width) * (
+ (pivot.x - canvasData.left) / width
+ );
+ canvasData.top -= (newHeight - height) * (
+ (pivot.y - canvasData.top) / height
+ );
+ } else {
+ // Zoom from the center of the canvas
+ canvasData.left -= (newWidth - width) / 2;
+ canvasData.top -= (newHeight - height) / 2;
+ }
+
+ canvasData.width = newWidth;
+ canvasData.height = newHeight;
+ this.renderCanvas(true);
+ }
+
+ return this;
+ },
+
+ /**
+ * Rotate the canvas with a relative degree
+ * @param {number} degree - The rotate degree.
+ * @returns {Object} this
+ */
+ rotate(degree) {
+ return this.rotateTo((this.imageData.rotate || 0) + Number(degree));
+ },
+
+ /**
+ * Rotate the canvas to an absolute degree
+ * @param {number} degree - The rotate degree.
+ * @returns {Object} this
+ */
+ rotateTo(degree) {
+ degree = Number(degree);
+
+ if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) {
+ this.imageData.rotate = degree % 360;
+ this.renderCanvas(true, true);
+ }
+
+ return this;
+ },
+
+ /**
+ * Scale the image on the x-axis.
+ * @param {number} scaleX - The scale ratio on the x-axis.
+ * @returns {Object} this
+ */
+ scaleX(scaleX) {
+ const { scaleY } = this.imageData;
+
+ return this.scale(scaleX, isNumber(scaleY) ? scaleY : 1);
+ },
+
+ /**
+ * Scale the image on the y-axis.
+ * @param {number} scaleY - The scale ratio on the y-axis.
+ * @returns {Object} this
+ */
+ scaleY(scaleY) {
+ const { scaleX } = this.imageData;
+
+ return this.scale(isNumber(scaleX) ? scaleX : 1, scaleY);
+ },
+
+ /**
+ * Scale the image
+ * @param {number} scaleX - The scale ratio on the x-axis.
+ * @param {number} [scaleY=scaleX] - The scale ratio on the y-axis.
+ * @returns {Object} this
+ */
+ scale(scaleX, scaleY = scaleX) {
+ const { imageData } = this;
+ let transformed = false;
+
+ scaleX = Number(scaleX);
+ scaleY = Number(scaleY);
+
+ if (this.ready && !this.disabled && this.options.scalable) {
+ if (isNumber(scaleX)) {
+ imageData.scaleX = scaleX;
+ transformed = true;
+ }
+
+ if (isNumber(scaleY)) {
+ imageData.scaleY = scaleY;
+ transformed = true;
+ }
+
+ if (transformed) {
+ this.renderCanvas(true, true);
+ }
+ }
+
+ return this;
+ },
+
+ /**
+ * Get the cropped area position and size data (base on the original image)
+ * @param {boolean} [rounded=false] - Indicate if round the data values or not.
+ * @returns {Object} The result cropped data.
+ */
+ getData(rounded = false) {
+ const {
+ options,
+ imageData,
+ canvasData,
+ cropBoxData,
+ } = this;
+ let data;
+
+ if (this.ready && this.cropped) {
+ data = {
+ x: cropBoxData.left - canvasData.left,
+ y: cropBoxData.top - canvasData.top,
+ width: cropBoxData.width,
+ height: cropBoxData.height,
+ };
+
+ const ratio = imageData.width / imageData.naturalWidth;
+
+ each(data, (n, i) => {
+ n /= ratio;
+ data[i] = rounded ? Math.round(n) : n;
+ });
+ } else {
+ data = {
+ x: 0,
+ y: 0,
+ width: 0,
+ height: 0,
+ };
+ }
+
+ if (options.rotatable) {
+ data.rotate = imageData.rotate || 0;
+ }
+
+ if (options.scalable) {
+ data.scaleX = imageData.scaleX || 1;
+ data.scaleY = imageData.scaleY || 1;
+ }
+
+ return data;
+ },
+
+ /**
+ * Set the cropped area position and size with new data
+ * @param {Object} data - The new data.
+ * @returns {Object} this
+ */
+ setData(data) {
+ const { options, imageData, canvasData } = this;
+ const cropBoxData = {};
+
+ if (isFunction(data)) {
+ data = data.call(this.element);
+ }
+
+ if (this.ready && !this.disabled && isPlainObject(data)) {
+ let transformed = false;
+
+ if (options.rotatable) {
+ if (isNumber(data.rotate) && data.rotate !== imageData.rotate) {
+ imageData.rotate = data.rotate;
+ transformed = true;
+ }
+ }
+
+ if (options.scalable) {
+ if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) {
+ imageData.scaleX = data.scaleX;
+ transformed = true;
+ }
+
+ if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) {
+ imageData.scaleY = data.scaleY;
+ transformed = true;
+ }
+ }
+
+ if (transformed) {
+ this.renderCanvas(true, true);
+ }
+
+ const ratio = imageData.width / imageData.naturalWidth;
+
+ if (isNumber(data.x)) {
+ cropBoxData.left = (data.x * ratio) + canvasData.left;
+ }
+
+ if (isNumber(data.y)) {
+ cropBoxData.top = (data.y * ratio) + canvasData.top;
+ }
+
+ if (isNumber(data.width)) {
+ cropBoxData.width = data.width * ratio;
+ }
+
+ if (isNumber(data.height)) {
+ cropBoxData.height = data.height * ratio;
+ }
+
+ this.setCropBoxData(cropBoxData);
+ }
+
+ return this;
+ },
+
+ /**
+ * Get the container size data.
+ * @returns {Object} The result container data.
+ */
+ getContainerData() {
+ return this.ready ? extend({}, this.containerData) : {};
+ },
+
+ /**
+ * Get the image position and size data.
+ * @returns {Object} The result image data.
+ */
+ getImageData() {
+ return this.loaded ? extend({}, this.imageData) : {};
+ },
+
+ /**
+ * Get the canvas position and size data.
+ * @returns {Object} The result canvas data.
+ */
+ getCanvasData() {
+ const { canvasData } = this;
+ const data = {};
+
+ if (this.ready) {
+ each([
+ 'left',
+ 'top',
+ 'width',
+ 'height',
+ 'naturalWidth',
+ 'naturalHeight',
+ ], (n) => {
+ data[n] = canvasData[n];
+ });
+ }
+
+ return data;
+ },
+
+ /**
+ * Set the canvas position and size with new data.
+ * @param {Object} data - The new canvas data.
+ * @returns {Object} this
+ */
+ setCanvasData(data) {
+ const { canvasData } = this;
+ const { aspectRatio } = canvasData;
+
+ if (isFunction(data)) {
+ data = data.call(this.element);
+ }
+
+ if (this.ready && !this.disabled && isPlainObject(data)) {
+ if (isNumber(data.left)) {
+ canvasData.left = data.left;
+ }
+
+ if (isNumber(data.top)) {
+ canvasData.top = data.top;
+ }
+
+ if (isNumber(data.width)) {
+ canvasData.width = data.width;
+ canvasData.height = data.width / aspectRatio;
+ } else if (isNumber(data.height)) {
+ canvasData.height = data.height;
+ canvasData.width = data.height * aspectRatio;
+ }
+
+ this.renderCanvas(true);
+ }
+
+ return this;
+ },
+
+ /**
+ * Get the crop box position and size data.
+ * @returns {Object} The result crop box data.
+ */
+ getCropBoxData() {
+ const { cropBoxData } = this;
+ let data;
+
+ if (this.ready && this.cropped) {
+ data = {
+ left: cropBoxData.left,
+ top: cropBoxData.top,
+ width: cropBoxData.width,
+ height: cropBoxData.height,
+ };
+ }
+
+ return data || {};
+ },
+
+ /**
+ * Set the crop box position and size with new data.
+ * @param {Object} data - The new crop box data.
+ * @returns {Object} this
+ */
+ setCropBoxData(data) {
+ const { cropBoxData } = this;
+ const { aspectRatio } = this.options;
+ let widthChanged;
+ let heightChanged;
+
+ if (isFunction(data)) {
+ data = data.call(this.element);
+ }
+
+ if (this.ready && this.cropped && !this.disabled && isPlainObject(data)) {
+ if (isNumber(data.left)) {
+ cropBoxData.left = data.left;
+ }
+
+ if (isNumber(data.top)) {
+ cropBoxData.top = data.top;
+ }
+
+ if (isNumber(data.width) && data.width !== cropBoxData.width) {
+ widthChanged = true;
+ cropBoxData.width = data.width;
+ }
+
+ if (isNumber(data.height) && data.height !== cropBoxData.height) {
+ heightChanged = true;
+ cropBoxData.height = data.height;
+ }
+
+ if (aspectRatio) {
+ if (widthChanged) {
+ cropBoxData.height = cropBoxData.width / aspectRatio;
+ } else if (heightChanged) {
+ cropBoxData.width = cropBoxData.height * aspectRatio;
+ }
+ }
+
+ this.renderCropBox();
+ }
+
+ return this;
+ },
+
+ /**
+ * Get a canvas drawn the cropped image.
+ * @param {Object} [options={}] - The config options.
+ * @returns {HTMLCanvasElement} - The result canvas.
+ */
+ getCroppedCanvas(options = {}) {
+ if (!this.ready || !window.HTMLCanvasElement) {
+ return null;
+ }
+
+ const { canvasData } = this;
+ const source = getSourceCanvas(this.image, this.imageData, canvasData, options);
+
+ // Returns the source canvas if it is not cropped.
+ if (!this.cropped) {
+ return source;
+ }
+
+ let {
+ x: initialX,
+ y: initialY,
+ width: initialWidth,
+ height: initialHeight,
+ } = this.getData();
+ const ratio = source.width / Math.floor(canvasData.naturalWidth);
+
+ if (ratio !== 1) {
+ initialX *= ratio;
+ initialY *= ratio;
+ initialWidth *= ratio;
+ initialHeight *= ratio;
+ }
+
+ const aspectRatio = initialWidth / initialHeight;
+ const maxSizes = getAdjustedSizes({
+ aspectRatio,
+ width: options.maxWidth || Infinity,
+ height: options.maxHeight || Infinity,
+ });
+ const minSizes = getAdjustedSizes({
+ aspectRatio,
+ width: options.minWidth || 0,
+ height: options.minHeight || 0,
+ }, 'cover');
+ let {
+ width,
+ height,
+ } = getAdjustedSizes({
+ aspectRatio,
+ width: options.width || (ratio !== 1 ? source.width : initialWidth),
+ height: options.height || (ratio !== 1 ? source.height : initialHeight),
+ });
+
+ width = Math.min(maxSizes.width, Math.max(minSizes.width, width));
+ height = Math.min(maxSizes.height, Math.max(minSizes.height, height));
+
+ const canvas = document.createElement('canvas');
+ const context = canvas.getContext('2d');
+
+ canvas.width = normalizeDecimalNumber(width);
+ canvas.height = normalizeDecimalNumber(height);
+
+ context.fillStyle = options.fillColor || 'transparent';
+ context.fillRect(0, 0, width, height);
+
+ const { imageSmoothingEnabled = true, imageSmoothingQuality } = options;
+
+ context.imageSmoothingEnabled = imageSmoothingEnabled;
+
+ if (imageSmoothingQuality) {
+ context.imageSmoothingQuality = imageSmoothingQuality;
+ }
+
+ // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage
+ const sourceWidth = source.width;
+ const sourceHeight = source.height;
+
+ // Source canvas parameters
+ let srcX = initialX;
+ let srcY = initialY;
+ let srcWidth;
+ let srcHeight;
+
+ // Destination canvas parameters
+ let dstX;
+ let dstY;
+ let dstWidth;
+ let dstHeight;
+
+ if (srcX <= -initialWidth || srcX > sourceWidth) {
+ srcX = 0;
+ srcWidth = 0;
+ dstX = 0;
+ dstWidth = 0;
+ } else if (srcX <= 0) {
+ dstX = -srcX;
+ srcX = 0;
+ srcWidth = Math.min(sourceWidth, initialWidth + srcX);
+ dstWidth = srcWidth;
+ } else if (srcX <= sourceWidth) {
+ dstX = 0;
+ srcWidth = Math.min(initialWidth, sourceWidth - srcX);
+ dstWidth = srcWidth;
+ }
+
+ if (srcWidth <= 0 || srcY <= -initialHeight || srcY > sourceHeight) {
+ srcY = 0;
+ srcHeight = 0;
+ dstY = 0;
+ dstHeight = 0;
+ } else if (srcY <= 0) {
+ dstY = -srcY;
+ srcY = 0;
+ srcHeight = Math.min(sourceHeight, initialHeight + srcY);
+ dstHeight = srcHeight;
+ } else if (srcY <= sourceHeight) {
+ dstY = 0;
+ srcHeight = Math.min(initialHeight, sourceHeight - srcY);
+ dstHeight = srcHeight;
+ }
+
+ // All the numerical parameters should be integer for `drawImage`
+ // https://github.com/fengyuanchen/cropper/issues/476
+ const params = [
+ srcX,
+ srcY,
+ srcWidth,
+ srcHeight,
+ ];
+
+ // Avoid "IndexSizeError"
+ if (dstWidth > 0 && dstHeight > 0) {
+ const scale = width / initialWidth;
+
+ params.push(
+ dstX * scale,
+ dstY * scale,
+ dstWidth * scale,
+ dstHeight * scale,
+ );
+ }
+
+ context.drawImage(source, ...params.map(param => Math.floor(normalizeDecimalNumber(param))));
+
+ return canvas;
+ },
+
+ /**
+ * Change the aspect ratio of the crop box.
+ * @param {number} aspectRatio - The new aspect ratio.
+ * @returns {Object} this
+ */
+ setAspectRatio(aspectRatio) {
+ const { options } = this;
+
+ if (!this.disabled && !isUndefined(aspectRatio)) {
+ // 0 -> NaN
+ options.aspectRatio = Math.max(0, aspectRatio) || NaN;
+
+ if (this.ready) {
+ this.initCropBox();
+
+ if (this.cropped) {
+ this.renderCropBox();
+ }
+ }
+ }
+
+ return this;
+ },
+
+ /**
+ * Change the drag mode.
+ * @param {string} mode - The new drag mode.
+ * @returns {Object} this
+ */
+ setDragMode(mode) {
+ const { options, dragBox, face } = this;
+
+ if (this.loaded && !this.disabled) {
+ const croppable = mode === DRAG_MODE_CROP;
+ const movable = options.movable && mode === DRAG_MODE_MOVE;
+
+ mode = (croppable || movable) ? mode : DRAG_MODE_NONE;
+
+ setData(dragBox, DATA_ACTION, mode);
+ toggleClass(dragBox, CLASS_CROP, croppable);
+ toggleClass(dragBox, CLASS_MOVE, movable);
+
+ if (!options.cropBoxMovable) {
+ // Sync drag mode to crop box when it is not movable
+ setData(face, DATA_ACTION, mode);
+ toggleClass(face, CLASS_CROP, croppable);
+ toggleClass(face, CLASS_MOVE, movable);
+ }
+ }
+
+ return this;
+ },
+};
diff --git a/library/cropperjs/src/js/preview.js b/library/cropperjs/src/js/preview.js
new file mode 100644
index 000000000..c47d03f4b
--- /dev/null
+++ b/library/cropperjs/src/js/preview.js
@@ -0,0 +1,142 @@
+import {
+ DATA_PREVIEW,
+} from './constants';
+import {
+ each,
+ empty,
+ extend,
+ getData,
+ getTransforms,
+ removeData,
+ setData,
+ setStyle,
+} from './utilities';
+
+export default {
+ initPreview() {
+ const { crossOrigin } = this;
+ const { preview } = this.options;
+ const url = crossOrigin ? this.crossOriginUrl : this.url;
+ const image = document.createElement('img');
+
+ if (crossOrigin) {
+ image.crossOrigin = crossOrigin;
+ }
+
+ image.src = url;
+ this.viewBox.appendChild(image);
+ this.image2 = image;
+
+ if (!preview) {
+ return;
+ }
+
+ const previews = preview.querySelector ? [preview] : document.querySelectorAll(preview);
+
+ this.previews = previews;
+
+ each(previews, (element) => {
+ const img = document.createElement('img');
+
+ // Save the original size for recover
+ setData(element, DATA_PREVIEW, {
+ width: element.offsetWidth,
+ height: element.offsetHeight,
+ html: element.innerHTML,
+ });
+
+ if (crossOrigin) {
+ img.crossOrigin = crossOrigin;
+ }
+
+ img.src = url;
+
+ /**
+ * Override img element styles
+ * Add `display:block` to avoid margin top issue
+ * Add `height:auto` to override `height` attribute on IE8
+ * (Occur only when margin-top <= -height)
+ */
+ img.style.cssText = (
+ 'display:block;' +
+ 'width:100%;' +
+ 'height:auto;' +
+ 'min-width:0!important;' +
+ 'min-height:0!important;' +
+ 'max-width:none!important;' +
+ 'max-height:none!important;' +
+ 'image-orientation:0deg!important;"'
+ );
+
+ empty(element);
+ element.appendChild(img);
+ });
+ },
+
+ resetPreview() {
+ each(this.previews, (element) => {
+ const data = getData(element, DATA_PREVIEW);
+
+ setStyle(element, {
+ width: data.width,
+ height: data.height,
+ });
+
+ element.innerHTML = data.html;
+ removeData(element, DATA_PREVIEW);
+ });
+ },
+
+ preview() {
+ const { imageData, canvasData, cropBoxData } = this;
+ const { width: cropBoxWidth, height: cropBoxHeight } = cropBoxData;
+ const { width, height } = imageData;
+ const left = cropBoxData.left - canvasData.left - imageData.left;
+ const top = cropBoxData.top - canvasData.top - imageData.top;
+
+ if (!this.cropped || this.disabled) {
+ return;
+ }
+
+ setStyle(this.image2, extend({
+ width,
+ height,
+ }, getTransforms(extend({
+ translateX: -left,
+ translateY: -top,
+ }, imageData))));
+
+ each(this.previews, (element) => {
+ const data = getData(element, DATA_PREVIEW);
+ const originalWidth = data.width;
+ const originalHeight = data.height;
+ let newWidth = originalWidth;
+ let newHeight = originalHeight;
+ let ratio = 1;
+
+ if (cropBoxWidth) {
+ ratio = originalWidth / cropBoxWidth;
+ newHeight = cropBoxHeight * ratio;
+ }
+
+ if (cropBoxHeight && newHeight > originalHeight) {
+ ratio = originalHeight / cropBoxHeight;
+ newWidth = cropBoxWidth * ratio;
+ newHeight = originalHeight;
+ }
+
+ setStyle(element, {
+ width: newWidth,
+ height: newHeight,
+ });
+
+ setStyle(element.getElementsByTagName('img')[0], extend({
+ width: width * ratio,
+ height: height * ratio,
+ }, getTransforms(extend({
+ translateX: -left * ratio,
+ translateY: -top * ratio,
+ }, imageData))));
+ });
+ },
+};
diff --git a/library/cropperjs/src/js/render.js b/library/cropperjs/src/js/render.js
new file mode 100644
index 000000000..09085ce41
--- /dev/null
+++ b/library/cropperjs/src/js/render.js
@@ -0,0 +1,495 @@
+import {
+ ACTION_ALL,
+ ACTION_MOVE,
+ CLASS_HIDDEN,
+ DATA_ACTION,
+ EVENT_CROP,
+} from './constants';
+import {
+ addClass,
+ dispatchEvent,
+ extend,
+ getAdjustedSizes,
+ getRotatedSizes,
+ getTransforms,
+ removeClass,
+ setData,
+ setStyle,
+} from './utilities';
+
+export default {
+ render() {
+ this.initContainer();
+ this.initCanvas();
+ this.initCropBox();
+ this.renderCanvas();
+
+ if (this.cropped) {
+ this.renderCropBox();
+ }
+ },
+
+ initContainer() {
+ const {
+ element,
+ options,
+ container,
+ cropper,
+ } = this;
+
+ addClass(cropper, CLASS_HIDDEN);
+ removeClass(element, CLASS_HIDDEN);
+
+ const containerData = {
+ width: Math.max(
+ container.offsetWidth,
+ Number(options.minContainerWidth) || 200,
+ ),
+ height: Math.max(
+ container.offsetHeight,
+ Number(options.minContainerHeight) || 100,
+ ),
+ };
+
+ this.containerData = containerData;
+
+ setStyle(cropper, {
+ width: containerData.width,
+ height: containerData.height,
+ });
+
+ addClass(element, CLASS_HIDDEN);
+ removeClass(cropper, CLASS_HIDDEN);
+ },
+
+ // Canvas (image wrapper)
+ initCanvas() {
+ const { containerData, imageData } = this;
+ const { viewMode } = this.options;
+ const rotated = Math.abs(imageData.rotate) % 180 === 90;
+ const naturalWidth = rotated ? imageData.naturalHeight : imageData.naturalWidth;
+ const naturalHeight = rotated ? imageData.naturalWidth : imageData.naturalHeight;
+ const aspectRatio = naturalWidth / naturalHeight;
+ let canvasWidth = containerData.width;
+ let canvasHeight = containerData.height;
+
+ if (containerData.height * aspectRatio > containerData.width) {
+ if (viewMode === 3) {
+ canvasWidth = containerData.height * aspectRatio;
+ } else {
+ canvasHeight = containerData.width / aspectRatio;
+ }
+ } else if (viewMode === 3) {
+ canvasHeight = containerData.width / aspectRatio;
+ } else {
+ canvasWidth = containerData.height * aspectRatio;
+ }
+
+ const canvasData = {
+ aspectRatio,
+ naturalWidth,
+ naturalHeight,
+ width: canvasWidth,
+ height: canvasHeight,
+ };
+
+ canvasData.left = (containerData.width - canvasWidth) / 2;
+ canvasData.top = (containerData.height - canvasHeight) / 2;
+ canvasData.oldLeft = canvasData.left;
+ canvasData.oldTop = canvasData.top;
+
+ this.canvasData = canvasData;
+ this.limited = (viewMode === 1 || viewMode === 2);
+ this.limitCanvas(true, true);
+ this.initialImageData = extend({}, imageData);
+ this.initialCanvasData = extend({}, canvasData);
+ },
+
+ limitCanvas(sizeLimited, positionLimited) {
+ const {
+ options,
+ containerData,
+ canvasData,
+ cropBoxData,
+ } = this;
+ const { viewMode } = options;
+ const { aspectRatio } = canvasData;
+ const cropped = this.cropped && cropBoxData;
+
+ if (sizeLimited) {
+ let minCanvasWidth = Number(options.minCanvasWidth) || 0;
+ let minCanvasHeight = Number(options.minCanvasHeight) || 0;
+
+ if (viewMode > 1) {
+ minCanvasWidth = Math.max(minCanvasWidth, containerData.width);
+ minCanvasHeight = Math.max(minCanvasHeight, containerData.height);
+
+ if (viewMode === 3) {
+ if (minCanvasHeight * aspectRatio > minCanvasWidth) {
+ minCanvasWidth = minCanvasHeight * aspectRatio;
+ } else {
+ minCanvasHeight = minCanvasWidth / aspectRatio;
+ }
+ }
+ } else if (viewMode > 0) {
+ if (minCanvasWidth) {
+ minCanvasWidth = Math.max(
+ minCanvasWidth,
+ cropped ? cropBoxData.width : 0,
+ );
+ } else if (minCanvasHeight) {
+ minCanvasHeight = Math.max(
+ minCanvasHeight,
+ cropped ? cropBoxData.height : 0,
+ );
+ } else if (cropped) {
+ minCanvasWidth = cropBoxData.width;
+ minCanvasHeight = cropBoxData.height;
+
+ if (minCanvasHeight * aspectRatio > minCanvasWidth) {
+ minCanvasWidth = minCanvasHeight * aspectRatio;
+ } else {
+ minCanvasHeight = minCanvasWidth / aspectRatio;
+ }
+ }
+ }
+
+ ({ width: minCanvasWidth, height: minCanvasHeight } = getAdjustedSizes({
+ aspectRatio,
+ width: minCanvasWidth,
+ height: minCanvasHeight,
+ }, 'cover'));
+
+ canvasData.minWidth = minCanvasWidth;
+ canvasData.minHeight = minCanvasHeight;
+ canvasData.maxWidth = Infinity;
+ canvasData.maxHeight = Infinity;
+ }
+
+ if (positionLimited) {
+ if (viewMode) {
+ const newCanvasLeft = containerData.width - canvasData.width;
+ const newCanvasTop = containerData.height - canvasData.height;
+
+ canvasData.minLeft = Math.min(0, newCanvasLeft);
+ canvasData.minTop = Math.min(0, newCanvasTop);
+ canvasData.maxLeft = Math.max(0, newCanvasLeft);
+ canvasData.maxTop = Math.max(0, newCanvasTop);
+
+ if (cropped && this.limited) {
+ canvasData.minLeft = Math.min(
+ cropBoxData.left,
+ cropBoxData.left + (cropBoxData.width - canvasData.width),
+ );
+ canvasData.minTop = Math.min(
+ cropBoxData.top,
+ cropBoxData.top + (cropBoxData.height - canvasData.height),
+ );
+ canvasData.maxLeft = cropBoxData.left;
+ canvasData.maxTop = cropBoxData.top;
+
+ if (viewMode === 2) {
+ if (canvasData.width >= containerData.width) {
+ canvasData.minLeft = Math.min(0, newCanvasLeft);
+ canvasData.maxLeft = Math.max(0, newCanvasLeft);
+ }
+
+ if (canvasData.height >= containerData.height) {
+ canvasData.minTop = Math.min(0, newCanvasTop);
+ canvasData.maxTop = Math.max(0, newCanvasTop);
+ }
+ }
+ }
+ } else {
+ canvasData.minLeft = -canvasData.width;
+ canvasData.minTop = -canvasData.height;
+ canvasData.maxLeft = containerData.width;
+ canvasData.maxTop = containerData.height;
+ }
+ }
+ },
+
+ renderCanvas(changed, transformed) {
+ const { canvasData, imageData } = this;
+
+ if (transformed) {
+ const { width: naturalWidth, height: naturalHeight } = getRotatedSizes({
+ width: imageData.naturalWidth * Math.abs(imageData.scaleX || 1),
+ height: imageData.naturalHeight * Math.abs(imageData.scaleY || 1),
+ degree: imageData.rotate || 0,
+ });
+ const width = canvasData.width * (naturalWidth / canvasData.naturalWidth);
+ const height = canvasData.height * (naturalHeight / canvasData.naturalHeight);
+
+ canvasData.left -= (width - canvasData.width) / 2;
+ canvasData.top -= (height - canvasData.height) / 2;
+ canvasData.width = width;
+ canvasData.height = height;
+ canvasData.aspectRatio = naturalWidth / naturalHeight;
+ canvasData.naturalWidth = naturalWidth;
+ canvasData.naturalHeight = naturalHeight;
+ this.limitCanvas(true, false);
+ }
+
+ if (canvasData.width > canvasData.maxWidth ||
+ canvasData.width < canvasData.minWidth) {
+ canvasData.left = canvasData.oldLeft;
+ }
+
+ if (canvasData.height > canvasData.maxHeight ||
+ canvasData.height < canvasData.minHeight) {
+ canvasData.top = canvasData.oldTop;
+ }
+
+ canvasData.width = Math.min(
+ Math.max(canvasData.width, canvasData.minWidth),
+ canvasData.maxWidth,
+ );
+ canvasData.height = Math.min(
+ Math.max(canvasData.height, canvasData.minHeight),
+ canvasData.maxHeight,
+ );
+
+ this.limitCanvas(false, true);
+
+ canvasData.left = Math.min(
+ Math.max(canvasData.left, canvasData.minLeft),
+ canvasData.maxLeft,
+ );
+ canvasData.top = Math.min(
+ Math.max(canvasData.top, canvasData.minTop),
+ canvasData.maxTop,
+ );
+ canvasData.oldLeft = canvasData.left;
+ canvasData.oldTop = canvasData.top;
+
+ setStyle(this.canvas, extend({
+ width: canvasData.width,
+ height: canvasData.height,
+ }, getTransforms({
+ translateX: canvasData.left,
+ translateY: canvasData.top,
+ })));
+
+ this.renderImage(changed);
+
+ if (this.cropped && this.limited) {
+ this.limitCropBox(true, true);
+ }
+ },
+
+ renderImage(changed) {
+ const { canvasData, imageData } = this;
+ const width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth);
+ const height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight);
+
+ extend(imageData, {
+ width,
+ height,
+ left: (canvasData.width - width) / 2,
+ top: (canvasData.height - height) / 2,
+ });
+ setStyle(this.image, extend({
+ width: imageData.width,
+ height: imageData.height,
+ }, getTransforms(extend({
+ translateX: imageData.left,
+ translateY: imageData.top,
+ }, imageData))));
+
+ if (changed) {
+ this.output();
+ }
+ },
+
+ initCropBox() {
+ const { options, canvasData } = this;
+ const { aspectRatio } = options;
+ const autoCropArea = Number(options.autoCropArea) || 0.8;
+ const cropBoxData = {
+ width: canvasData.width,
+ height: canvasData.height,
+ };
+
+ if (aspectRatio) {
+ if (canvasData.height * aspectRatio > canvasData.width) {
+ cropBoxData.height = cropBoxData.width / aspectRatio;
+ } else {
+ cropBoxData.width = cropBoxData.height * aspectRatio;
+ }
+ }
+
+ this.cropBoxData = cropBoxData;
+ this.limitCropBox(true, true);
+
+ // Initialize auto crop area
+ cropBoxData.width = Math.min(
+ Math.max(cropBoxData.width, cropBoxData.minWidth),
+ cropBoxData.maxWidth,
+ );
+ cropBoxData.height = Math.min(
+ Math.max(cropBoxData.height, cropBoxData.minHeight),
+ cropBoxData.maxHeight,
+ );
+
+ // The width/height of auto crop area must large than "minWidth/Height"
+ cropBoxData.width = Math.max(
+ cropBoxData.minWidth,
+ cropBoxData.width * autoCropArea,
+ );
+ cropBoxData.height = Math.max(
+ cropBoxData.minHeight,
+ cropBoxData.height * autoCropArea,
+ );
+ cropBoxData.left = (
+ canvasData.left + ((canvasData.width - cropBoxData.width) / 2)
+ );
+ cropBoxData.top = (
+ canvasData.top + ((canvasData.height - cropBoxData.height) / 2)
+ );
+ cropBoxData.oldLeft = cropBoxData.left;
+ cropBoxData.oldTop = cropBoxData.top;
+
+ this.initialCropBoxData = extend({}, cropBoxData);
+ },
+
+ limitCropBox(sizeLimited, positionLimited) {
+ const {
+ options,
+ containerData,
+ canvasData,
+ cropBoxData,
+ limited,
+ } = this;
+ const { aspectRatio } = options;
+
+ if (sizeLimited) {
+ let minCropBoxWidth = Number(options.minCropBoxWidth) || 0;
+ let minCropBoxHeight = Number(options.minCropBoxHeight) || 0;
+ let maxCropBoxWidth = Math.min(
+ containerData.width,
+ limited ? canvasData.width : containerData.width,
+ );
+ let maxCropBoxHeight = Math.min(
+ containerData.height,
+ limited ? canvasData.height : containerData.height,
+ );
+
+ // The min/maxCropBoxWidth/Height must be less than container's width/height
+ minCropBoxWidth = Math.min(minCropBoxWidth, containerData.width);
+ minCropBoxHeight = Math.min(minCropBoxHeight, containerData.height);
+
+ if (aspectRatio) {
+ if (minCropBoxWidth && minCropBoxHeight) {
+ if (minCropBoxHeight * aspectRatio > minCropBoxWidth) {
+ minCropBoxHeight = minCropBoxWidth / aspectRatio;
+ } else {
+ minCropBoxWidth = minCropBoxHeight * aspectRatio;
+ }
+ } else if (minCropBoxWidth) {
+ minCropBoxHeight = minCropBoxWidth / aspectRatio;
+ } else if (minCropBoxHeight) {
+ minCropBoxWidth = minCropBoxHeight * aspectRatio;
+ }
+
+ if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) {
+ maxCropBoxHeight = maxCropBoxWidth / aspectRatio;
+ } else {
+ maxCropBoxWidth = maxCropBoxHeight * aspectRatio;
+ }
+ }
+
+ // The minWidth/Height must be less than maxWidth/Height
+ cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth);
+ cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight);
+ cropBoxData.maxWidth = maxCropBoxWidth;
+ cropBoxData.maxHeight = maxCropBoxHeight;
+ }
+
+ if (positionLimited) {
+ if (limited) {
+ cropBoxData.minLeft = Math.max(0, canvasData.left);
+ cropBoxData.minTop = Math.max(0, canvasData.top);
+ cropBoxData.maxLeft = Math.min(
+ containerData.width,
+ canvasData.left + canvasData.width,
+ ) - cropBoxData.width;
+ cropBoxData.maxTop = Math.min(
+ containerData.height,
+ canvasData.top + canvasData.height,
+ ) - cropBoxData.height;
+ } else {
+ cropBoxData.minLeft = 0;
+ cropBoxData.minTop = 0;
+ cropBoxData.maxLeft = containerData.width - cropBoxData.width;
+ cropBoxData.maxTop = containerData.height - cropBoxData.height;
+ }
+ }
+ },
+
+ renderCropBox() {
+ const { options, containerData, cropBoxData } = this;
+
+ if (cropBoxData.width > cropBoxData.maxWidth ||
+ cropBoxData.width < cropBoxData.minWidth) {
+ cropBoxData.left = cropBoxData.oldLeft;
+ }
+
+ if (cropBoxData.height > cropBoxData.maxHeight ||
+ cropBoxData.height < cropBoxData.minHeight) {
+ cropBoxData.top = cropBoxData.oldTop;
+ }
+
+ cropBoxData.width = Math.min(
+ Math.max(cropBoxData.width, cropBoxData.minWidth),
+ cropBoxData.maxWidth,
+ );
+ cropBoxData.height = Math.min(
+ Math.max(cropBoxData.height, cropBoxData.minHeight),
+ cropBoxData.maxHeight,
+ );
+
+ this.limitCropBox(false, true);
+
+ cropBoxData.left = Math.min(
+ Math.max(cropBoxData.left, cropBoxData.minLeft),
+ cropBoxData.maxLeft,
+ );
+ cropBoxData.top = Math.min(
+ Math.max(cropBoxData.top, cropBoxData.minTop),
+ cropBoxData.maxTop,
+ );
+ cropBoxData.oldLeft = cropBoxData.left;
+ cropBoxData.oldTop = cropBoxData.top;
+
+ if (options.movable && options.cropBoxMovable) {
+ // Turn to move the canvas when the crop box is equal to the container
+ setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width &&
+ cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL);
+ }
+
+ setStyle(this.cropBox, extend({
+ width: cropBoxData.width,
+ height: cropBoxData.height,
+ }, getTransforms({
+ translateX: cropBoxData.left,
+ translateY: cropBoxData.top,
+ })));
+
+ if (this.cropped && this.limited) {
+ this.limitCanvas(true, true);
+ }
+
+ if (!this.disabled) {
+ this.output();
+ }
+ },
+
+ output() {
+ this.preview();
+
+ if (this.complete) {
+ dispatchEvent(this.element, EVENT_CROP, this.getData());
+ }
+ },
+};
diff --git a/library/cropperjs/src/js/template.js b/library/cropperjs/src/js/template.js
new file mode 100644
index 000000000..589b46a78
--- /dev/null
+++ b/library/cropperjs/src/js/template.js
@@ -0,0 +1,27 @@
+export default (
+ '' +
+ '
' +
+ '
' +
+ '
' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ '
' +
+ '
'
+);
diff --git a/library/cropperjs/src/js/utilities.js b/library/cropperjs/src/js/utilities.js
new file mode 100644
index 000000000..50b586a76
--- /dev/null
+++ b/library/cropperjs/src/js/utilities.js
@@ -0,0 +1,985 @@
+import {
+ WINDOW,
+} from './constants';
+
+/**
+ * Check if the given value is not a number.
+ */
+export const isNaN = Number.isNaN || WINDOW.isNaN;
+
+/**
+ * Check if the given value is a number.
+ * @param {*} value - The value to check.
+ * @returns {boolean} Returns `true` if the given value is a number, else `false`.
+ */
+export function isNumber(value) {
+ return typeof value === 'number' && !isNaN(value);
+}
+
+/**
+ * Check if the given value is undefined.
+ * @param {*} value - The value to check.
+ * @returns {boolean} Returns `true` if the given value is undefined, else `false`.
+ */
+export function isUndefined(value) {
+ return typeof value === 'undefined';
+}
+
+/**
+ * Check if the given value is an object.
+ * @param {*} value - The value to check.
+ * @returns {boolean} Returns `true` if the given value is an object, else `false`.
+ */
+export function isObject(value) {
+ return typeof value === 'object' && value !== null;
+}
+
+const { hasOwnProperty } = Object.prototype;
+
+/**
+ * Check if the given value is a plain object.
+ * @param {*} value - The value to check.
+ * @returns {boolean} Returns `true` if the given value is a plain object, else `false`.
+ */
+export function isPlainObject(value) {
+ if (!isObject(value)) {
+ return false;
+ }
+
+ try {
+ const { constructor } = value;
+ const { prototype } = constructor;
+
+ return constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');
+ } catch (e) {
+ return false;
+ }
+}
+
+/**
+ * Check if the given value is a function.
+ * @param {*} value - The value to check.
+ * @returns {boolean} Returns `true` if the given value is a function, else `false`.
+ */
+export function isFunction(value) {
+ return typeof value === 'function';
+}
+
+/**
+ * Iterate the given data.
+ * @param {*} data - The data to iterate.
+ * @param {Function} callback - The process function for each element.
+ * @returns {*} The original data.
+ */
+export function each(data, callback) {
+ if (data && isFunction(callback)) {
+ if (Array.isArray(data) || isNumber(data.length)/* array-like */) {
+ const { length } = data;
+ let i;
+
+ for (i = 0; i < length; i += 1) {
+ if (callback.call(data, data[i], i, data) === false) {
+ break;
+ }
+ }
+ } else if (isObject(data)) {
+ Object.keys(data).forEach((key) => {
+ callback.call(data, data[key], key, data);
+ });
+ }
+ }
+
+ return data;
+}
+
+/**
+ * Extend the given object.
+ * @param {*} obj - The object to be extended.
+ * @param {*} args - The rest objects which will be merged to the first object.
+ * @returns {Object} The extended object.
+ */
+export function extend(obj, ...args) {
+ if (isObject(obj) && args.length > 0) {
+ if (Object.assign) {
+ return Object.assign(obj, ...args);
+ }
+
+ args.forEach((arg) => {
+ if (isObject(arg)) {
+ Object.keys(arg).forEach((key) => {
+ obj[key] = arg[key];
+ });
+ }
+ });
+ }
+
+ return obj;
+}
+
+/**
+ * Takes a function and returns a new one that will always have a particular context.
+ * @param {Function} fn - The target function.
+ * @param {Object} context - The new context for the function.
+ * @returns {boolean} The new function.
+ */
+export function proxy(fn, context, ...args) {
+ return (...args2) => fn.apply(context, args.concat(args2));
+}
+
+const REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/i;
+
+/**
+ * Normalize decimal number.
+ * Check out {@link http://0.30000000000000004.com/ }
+ * @param {number} value - The value to normalize.
+ * @param {number} [times=100000000000] - The times for normalizing.
+ * @returns {number} Returns the normalized number.
+ */
+export function normalizeDecimalNumber(value, times = 100000000000) {
+ return REGEXP_DECIMALS.test(value) ? (Math.round(value * times) / times) : value;
+}
+
+const REGEXP_SUFFIX = /^(?:width|height|left|top|marginLeft|marginTop)$/;
+
+/**
+ * Apply styles to the given element.
+ * @param {Element} element - The target element.
+ * @param {Object} styles - The styles for applying.
+ */
+export function setStyle(element, styles) {
+ const { style } = element;
+
+ each(styles, (value, property) => {
+ if (REGEXP_SUFFIX.test(property) && isNumber(value)) {
+ value += 'px';
+ }
+
+ style[property] = value;
+ });
+}
+
+/**
+ * Check if the given element has a special class.
+ * @param {Element} element - The element to check.
+ * @param {string} value - The class to search.
+ * @returns {boolean} Returns `true` if the special class was found.
+ */
+export function hasClass(element, value) {
+ return element.classList ?
+ element.classList.contains(value) :
+ element.className.indexOf(value) > -1;
+}
+
+/**
+ * Add classes to the given element.
+ * @param {Element} element - The target element.
+ * @param {string} value - The classes to be added.
+ */
+export function addClass(element, value) {
+ if (!value) {
+ return;
+ }
+
+ if (isNumber(element.length)) {
+ each(element, (elem) => {
+ addClass(elem, value);
+ });
+ return;
+ }
+
+ if (element.classList) {
+ element.classList.add(value);
+ return;
+ }
+
+ const className = element.className.trim();
+
+ if (!className) {
+ element.className = value;
+ } else if (className.indexOf(value) < 0) {
+ element.className = `${className} ${value}`;
+ }
+}
+
+/**
+ * Remove classes from the given element.
+ * @param {Element} element - The target element.
+ * @param {string} value - The classes to be removed.
+ */
+export function removeClass(element, value) {
+ if (!value) {
+ return;
+ }
+
+ if (isNumber(element.length)) {
+ each(element, (elem) => {
+ removeClass(elem, value);
+ });
+ return;
+ }
+
+ if (element.classList) {
+ element.classList.remove(value);
+ return;
+ }
+
+ if (element.className.indexOf(value) >= 0) {
+ element.className = element.className.replace(value, '');
+ }
+}
+
+/**
+ * Add or remove classes from the given element.
+ * @param {Element} element - The target element.
+ * @param {string} value - The classes to be toggled.
+ * @param {boolean} added - Add only.
+ */
+export function toggleClass(element, value, added) {
+ if (!value) {
+ return;
+ }
+
+ if (isNumber(element.length)) {
+ each(element, (elem) => {
+ toggleClass(elem, value, added);
+ });
+ return;
+ }
+
+ // IE10-11 doesn't support the second parameter of `classList.toggle`
+ if (added) {
+ addClass(element, value);
+ } else {
+ removeClass(element, value);
+ }
+}
+
+const REGEXP_HYPHENATE = /([a-z\d])([A-Z])/g;
+
+/**
+ * Hyphenate the given value.
+ * @param {string} value - The value to hyphenate.
+ * @returns {string} The hyphenated value.
+ */
+export function hyphenate(value) {
+ return value.replace(REGEXP_HYPHENATE, '$1-$2').toLowerCase();
+}
+
+/**
+ * Get data from the given element.
+ * @param {Element} element - The target element.
+ * @param {string} name - The data key to get.
+ * @returns {string} The data value.
+ */
+export function getData(element, name) {
+ if (isObject(element[name])) {
+ return element[name];
+ } else if (element.dataset) {
+ return element.dataset[name];
+ }
+
+ return element.getAttribute(`data-${hyphenate(name)}`);
+}
+
+/**
+ * Set data to the given element.
+ * @param {Element} element - The target element.
+ * @param {string} name - The data key to set.
+ * @param {string} data - The data value.
+ */
+export function setData(element, name, data) {
+ if (isObject(data)) {
+ element[name] = data;
+ } else if (element.dataset) {
+ element.dataset[name] = data;
+ } else {
+ element.setAttribute(`data-${hyphenate(name)}`, data);
+ }
+}
+
+/**
+ * Remove data from the given element.
+ * @param {Element} element - The target element.
+ * @param {string} name - The data key to remove.
+ */
+export function removeData(element, name) {
+ if (isObject(element[name])) {
+ try {
+ delete element[name];
+ } catch (e) {
+ element[name] = null;
+ }
+ } else if (element.dataset) {
+ // #128 Safari not allows to delete dataset property
+ try {
+ delete element.dataset[name];
+ } catch (e) {
+ element.dataset[name] = null;
+ }
+ } else {
+ element.removeAttribute(`data-${hyphenate(name)}`);
+ }
+}
+
+const REGEXP_SPACES = /\s\s*/;
+
+/**
+ * Remove event listener from the target element.
+ * @param {Element} element - The event target.
+ * @param {string} type - The event type(s).
+ * @param {Function} listener - The event listener.
+ * @param {Object} options - The event options.
+ */
+export function removeListener(element, type, listener, options = {}) {
+ if (!isFunction(listener)) {
+ return;
+ }
+
+ const types = type.trim().split(REGEXP_SPACES);
+
+ if (types.length > 1) {
+ each(types, (t) => {
+ removeListener(element, t, listener, options);
+ });
+ return;
+ }
+
+ if (element.removeEventListener) {
+ element.removeEventListener(type, listener, options);
+ } else if (element.detachEvent) {
+ element.detachEvent(`on${type}`, listener);
+ }
+}
+
+/**
+ * Add event listener to the target element.
+ * @param {Element} element - The event target.
+ * @param {string} type - The event type(s).
+ * @param {Function} listener - The event listener.
+ * @param {Object} options - The event options.
+ */
+export function addListener(element, type, listener, options = {}) {
+ if (!isFunction(listener)) {
+ return;
+ }
+
+ const types = type.trim().split(REGEXP_SPACES);
+
+ if (types.length > 1) {
+ each(types, (t) => {
+ addListener(element, t, listener, options);
+ });
+ return;
+ }
+
+ if (options.once) {
+ const originalListener = listener;
+
+ listener = (...args) => {
+ removeListener(element, type, listener, options);
+ return originalListener.apply(element, args);
+ };
+ }
+
+ if (element.addEventListener) {
+ element.addEventListener(type, listener, options);
+ } else if (element.attachEvent) {
+ element.attachEvent(`on${type}`, listener);
+ }
+}
+
+/**
+ * Dispatch event on the target element.
+ * @param {Element} element - The event target.
+ * @param {string} type - The event type(s).
+ * @param {Object} data - The additional event data.
+ * @returns {boolean} Indicate if the event is default prevented or not.
+ */
+export function dispatchEvent(element, type, data) {
+ if (element.dispatchEvent) {
+ let event;
+
+ // Event and CustomEvent on IE9-11 are global objects, not constructors
+ if (isFunction(Event) && isFunction(CustomEvent)) {
+ if (isUndefined(data)) {
+ event = new Event(type, {
+ bubbles: true,
+ cancelable: true,
+ });
+ } else {
+ event = new CustomEvent(type, {
+ detail: data,
+ bubbles: true,
+ cancelable: true,
+ });
+ }
+ } else if (isUndefined(data)) {
+ event = document.createEvent('Event');
+ event.initEvent(type, true, true);
+ } else {
+ event = document.createEvent('CustomEvent');
+ event.initCustomEvent(type, true, true, data);
+ }
+
+ // IE9+
+ return element.dispatchEvent(event);
+ } else if (element.fireEvent) {
+ // IE6-10 (native events only)
+ return element.fireEvent(`on${type}`);
+ }
+
+ return true;
+}
+
+/**
+ * Get the offset base on the document.
+ * @param {Element} element - The target element.
+ * @returns {Object} The offset data.
+ */
+export function getOffset(element) {
+ const doc = document.documentElement;
+ const box = element.getBoundingClientRect();
+
+ return {
+ left: box.left + (
+ (window.scrollX || (doc && doc.scrollLeft) || 0) - ((doc && doc.clientLeft) || 0)
+ ),
+ top: box.top + (
+ (window.scrollY || (doc && doc.scrollTop) || 0) - ((doc && doc.clientTop) || 0)
+ ),
+ };
+}
+
+/**
+ * Empty an element.
+ * @param {Element} element - The element to empty.
+ */
+export function empty(element) {
+ while (element.firstChild) {
+ element.removeChild(element.firstChild);
+ }
+}
+
+const { location } = WINDOW;
+const REGEXP_ORIGINS = /^(https?:)\/\/([^:/?#]+):?(\d*)/i;
+
+/**
+ * Check if the given URL is a cross origin URL.
+ * @param {string} url - The target URL.
+ * @returns {boolean} Returns `true` if the given URL is a cross origin URL, else `false`.
+ */
+export function isCrossOriginURL(url) {
+ const parts = url.match(REGEXP_ORIGINS);
+
+ return parts && (
+ parts[1] !== location.protocol ||
+ parts[2] !== location.hostname ||
+ parts[3] !== location.port
+ );
+}
+
+/**
+ * Add timestamp to the given URL.
+ * @param {string} url - The target URL.
+ * @returns {string} The result URL.
+ */
+export function addTimestamp(url) {
+ const timestamp = `timestamp=${(new Date()).getTime()}`;
+
+ return (url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp);
+}
+
+/**
+ * Get transforms base on the given object.
+ * @param {Object} obj - The target object.
+ * @returns {string} A string contains transform values.
+ */
+export function getTransforms({
+ rotate,
+ scaleX,
+ scaleY,
+ translateX,
+ translateY,
+}) {
+ const values = [];
+
+ if (isNumber(translateX) && translateX !== 0) {
+ values.push(`translateX(${translateX}px)`);
+ }
+
+ if (isNumber(translateY) && translateY !== 0) {
+ values.push(`translateY(${translateY}px)`);
+ }
+
+ // Rotate should come first before scale to match orientation transform
+ if (isNumber(rotate) && rotate !== 0) {
+ values.push(`rotate(${rotate}deg)`);
+ }
+
+ if (isNumber(scaleX) && scaleX !== 1) {
+ values.push(`scaleX(${scaleX})`);
+ }
+
+ if (isNumber(scaleY) && scaleY !== 1) {
+ values.push(`scaleY(${scaleY})`);
+ }
+
+ const transform = values.length ? values.join(' ') : 'none';
+
+ return {
+ WebkitTransform: transform,
+ msTransform: transform,
+ transform,
+ };
+}
+
+const { navigator } = WINDOW;
+const IS_SAFARI_OR_UIWEBVIEW = navigator && /(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(navigator.userAgent);
+
+/**
+ * Get an image's natural sizes.
+ * @param {string} image - The target image.
+ * @param {Function} callback - The callback function.
+ */
+export function getImageNaturalSizes(image, callback) {
+ // Modern browsers (except Safari)
+ if (image.naturalWidth && !IS_SAFARI_OR_UIWEBVIEW) {
+ callback(image.naturalWidth, image.naturalHeight);
+ return;
+ }
+
+ const newImage = document.createElement('img');
+ const body = document.body || document.documentElement;
+
+ newImage.onload = () => {
+ callback(newImage.width, newImage.height);
+
+ if (!IS_SAFARI_OR_UIWEBVIEW) {
+ body.removeChild(newImage);
+ }
+ };
+
+ newImage.src = image.src;
+
+ // iOS Safari will convert the image automatically
+ // with its orientation once append it into DOM (#279)
+ if (!IS_SAFARI_OR_UIWEBVIEW) {
+ newImage.style.cssText = (
+ 'left:0;' +
+ 'max-height:none!important;' +
+ 'max-width:none!important;' +
+ 'min-height:0!important;' +
+ 'min-width:0!important;' +
+ 'opacity:0;' +
+ 'position:absolute;' +
+ 'top:0;' +
+ 'z-index:-1;'
+ );
+ body.appendChild(newImage);
+ }
+}
+
+/**
+ * Get the max ratio of a group of pointers.
+ * @param {string} pointers - The target pointers.
+ * @returns {number} The result ratio.
+ */
+export function getMaxZoomRatio(pointers) {
+ const pointers2 = extend({}, pointers);
+ const ratios = [];
+
+ each(pointers, (pointer, pointerId) => {
+ delete pointers2[pointerId];
+
+ each(pointers2, (pointer2) => {
+ const x1 = Math.abs(pointer.startX - pointer2.startX);
+ const y1 = Math.abs(pointer.startY - pointer2.startY);
+ const x2 = Math.abs(pointer.endX - pointer2.endX);
+ const y2 = Math.abs(pointer.endY - pointer2.endY);
+ const z1 = Math.sqrt((x1 * x1) + (y1 * y1));
+ const z2 = Math.sqrt((x2 * x2) + (y2 * y2));
+ const ratio = (z2 - z1) / z1;
+
+ ratios.push(ratio);
+ });
+ });
+
+ ratios.sort((a, b) => Math.abs(a) < Math.abs(b));
+
+ return ratios[0];
+}
+
+/**
+ * Get a pointer from an event object.
+ * @param {Object} event - The target event object.
+ * @param {boolean} endOnly - Indicates if only returns the end point coordinate or not.
+ * @returns {Object} The result pointer contains start and/or end point coordinates.
+ */
+export function getPointer({ pageX, pageY }, endOnly) {
+ const end = {
+ endX: pageX,
+ endY: pageY,
+ };
+
+ if (endOnly) {
+ return end;
+ }
+
+ return extend({
+ startX: pageX,
+ startY: pageY,
+ }, end);
+}
+
+/**
+ * Get the center point coordinate of a group of pointers.
+ * @param {Object} pointers - The target pointers.
+ * @returns {Object} The center point coordinate.
+ */
+export function getPointersCenter(pointers) {
+ let pageX = 0;
+ let pageY = 0;
+ let count = 0;
+
+ each(pointers, ({ startX, startY }) => {
+ pageX += startX;
+ pageY += startY;
+ count += 1;
+ });
+
+ pageX /= count;
+ pageY /= count;
+
+ return {
+ pageX,
+ pageY,
+ };
+}
+
+/**
+ * Check if the given value is a finite number.
+ */
+export const isFinite = Number.isFinite || WINDOW.isFinite;
+
+/**
+ * Get the max sizes in a rectangle under the given aspect ratio.
+ * @param {Object} data - The original sizes.
+ * @param {string} [type='contain'] - The adjust type.
+ * @returns {Object} The result sizes.
+ */
+export function getAdjustedSizes(
+ {
+ aspectRatio,
+ height,
+ width,
+ },
+ type = 'contain', // or 'cover'
+) {
+ const isValidNumber = value => isFinite(value) && value > 0;
+
+ if (isValidNumber(width) && isValidNumber(height)) {
+ const adjustedWidth = height * aspectRatio;
+
+ if ((type === 'contain' && adjustedWidth > width) || (type === 'cover' && adjustedWidth < width)) {
+ height = width / aspectRatio;
+ } else {
+ width = height * aspectRatio;
+ }
+ } else if (isValidNumber(width)) {
+ height = width / aspectRatio;
+ } else if (isValidNumber(height)) {
+ width = height * aspectRatio;
+ }
+
+ return {
+ width,
+ height,
+ };
+}
+
+/**
+ * Get the new sizes of a rectangle after rotated.
+ * @param {Object} data - The original sizes.
+ * @returns {Object} The result sizes.
+ */
+export function getRotatedSizes({ width, height, degree }) {
+ degree = Math.abs(degree) % 180;
+
+ if (degree === 90) {
+ return {
+ width: height,
+ height: width,
+ };
+ }
+
+ const arc = ((degree % 90) * Math.PI) / 180;
+ const sinArc = Math.sin(arc);
+ const cosArc = Math.cos(arc);
+ const newWidth = (width * cosArc) + (height * sinArc);
+ const newHeight = (width * sinArc) + (height * cosArc);
+
+ return degree > 90 ? {
+ width: newHeight,
+ height: newWidth,
+ } : {
+ width: newWidth,
+ height: newHeight,
+ };
+}
+
+/**
+ * Get a canvas which drew the given image.
+ * @param {HTMLImageElement} image - The image for drawing.
+ * @param {Object} imageData - The image data.
+ * @param {Object} canvasData - The canvas data.
+ * @param {Object} options - The options.
+ * @returns {HTMLCanvasElement} The result canvas.
+ */
+export function getSourceCanvas(
+ image,
+ {
+ rotate = 0,
+ scaleX = 1,
+ scaleY = 1,
+ },
+ {
+ aspectRatio,
+ naturalWidth,
+ naturalHeight,
+ },
+ {
+ fillColor = 'transparent',
+ imageSmoothingEnabled = true,
+ imageSmoothingQuality = 'low',
+ maxWidth = Infinity,
+ maxHeight = Infinity,
+ minWidth = 0,
+ minHeight = 0,
+ },
+) {
+ const canvas = document.createElement('canvas');
+ const context = canvas.getContext('2d');
+ const maxSizes = getAdjustedSizes({
+ aspectRatio,
+ width: maxWidth,
+ height: maxHeight,
+ });
+ const minSizes = getAdjustedSizes({
+ aspectRatio,
+ width: minWidth,
+ height: minHeight,
+ }, 'cover');
+ const width = Math.min(maxSizes.width, Math.max(minSizes.width, naturalWidth));
+ const height = Math.min(maxSizes.height, Math.max(minSizes.height, naturalHeight));
+ const params = [
+ -width / 2,
+ -height / 2,
+ width,
+ height,
+ ];
+
+ canvas.width = normalizeDecimalNumber(width);
+ canvas.height = normalizeDecimalNumber(height);
+ context.fillStyle = fillColor;
+ context.fillRect(0, 0, width, height);
+ context.save();
+ context.translate(width / 2, height / 2);
+ context.rotate((rotate * Math.PI) / 180);
+ context.scale(scaleX, scaleY);
+ context.imageSmoothingEnabled = imageSmoothingEnabled;
+ context.imageSmoothingQuality = imageSmoothingQuality;
+ context.drawImage(image, ...params.map(param => Math.floor(normalizeDecimalNumber(param))));
+ context.restore();
+ return canvas;
+}
+
+const { fromCharCode } = String;
+
+/**
+ * Get string from char code in data view.
+ * @param {DataView} dataView - The data view for read.
+ * @param {number} start - The start index.
+ * @param {number} length - The read length.
+ * @returns {string} The read result.
+ */
+export function getStringFromCharCode(dataView, start, length) {
+ let str = '';
+ let i;
+
+ length += start;
+
+ for (i = start; i < length; i += 1) {
+ str += fromCharCode(dataView.getUint8(i));
+ }
+
+ return str;
+}
+
+const REGEXP_DATA_URL_HEAD = /^data:.*,/;
+
+/**
+ * Transform Data URL to array buffer.
+ * @param {string} dataURL - The Data URL to transform.
+ * @returns {ArrayBuffer} The result array buffer.
+ */
+export function dataURLToArrayBuffer(dataURL) {
+ const base64 = dataURL.replace(REGEXP_DATA_URL_HEAD, '');
+ const binary = atob(base64);
+ const arrayBuffer = new ArrayBuffer(binary.length);
+ const uint8 = new Uint8Array(arrayBuffer);
+
+ each(uint8, (value, i) => {
+ uint8[i] = binary.charCodeAt(i);
+ });
+
+ return arrayBuffer;
+}
+
+/**
+ * Transform array buffer to Data URL.
+ * @param {ArrayBuffer} arrayBuffer - The array buffer to transform.
+ * @param {string} mimeType - The mime type of the Data URL.
+ * @returns {string} The result Data URL.
+ */
+export function arrayBufferToDataURL(arrayBuffer, mimeType) {
+ const uint8 = new Uint8Array(arrayBuffer);
+ let data = '';
+
+ // TypedArray.prototype.forEach is not supported in some browsers.
+ each(uint8, (value) => {
+ data += fromCharCode(value);
+ });
+
+ return `data:${mimeType};base64,${btoa(data)}`;
+}
+
+/**
+ * Get orientation value from given array buffer.
+ * @param {ArrayBuffer} arrayBuffer - The array buffer to read.
+ * @returns {number} The read orientation value.
+ */
+export function getOrientation(arrayBuffer) {
+ const dataView = new DataView(arrayBuffer);
+ let orientation;
+ let littleEndian;
+ let app1Start;
+ let ifdStart;
+
+ // Only handle JPEG image (start by 0xFFD8)
+ if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
+ const length = dataView.byteLength;
+ let offset = 2;
+
+ while (offset < length) {
+ if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
+ app1Start = offset;
+ break;
+ }
+
+ offset += 1;
+ }
+ }
+
+ if (app1Start) {
+ const exifIDCode = app1Start + 4;
+ const tiffOffset = app1Start + 10;
+
+ if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
+ const endianness = dataView.getUint16(tiffOffset);
+
+ littleEndian = endianness === 0x4949;
+
+ if (littleEndian || endianness === 0x4D4D /* bigEndian */) {
+ if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
+ const firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
+
+ if (firstIFDOffset >= 0x00000008) {
+ ifdStart = tiffOffset + firstIFDOffset;
+ }
+ }
+ }
+ }
+ }
+
+ if (ifdStart) {
+ const length = dataView.getUint16(ifdStart, littleEndian);
+ let offset;
+ let i;
+
+ for (i = 0; i < length; i += 1) {
+ offset = ifdStart + (i * 12) + 2;
+
+ if (dataView.getUint16(offset, littleEndian) === 0x0112 /* Orientation */) {
+ // 8 is the offset of the current tag's value
+ offset += 8;
+
+ // Get the original orientation value
+ orientation = dataView.getUint16(offset, littleEndian);
+
+ // Override the orientation with its default value
+ dataView.setUint16(offset, 1, littleEndian);
+ break;
+ }
+ }
+ }
+
+ return orientation;
+}
+
+/**
+ * Parse Exif Orientation value.
+ * @param {number} orientation - The orientation to parse.
+ * @returns {Object} The parsed result.
+ */
+export function parseOrientation(orientation) {
+ let rotate = 0;
+ let scaleX = 1;
+ let scaleY = 1;
+
+ switch (orientation) {
+ // Flip horizontal
+ case 2:
+ scaleX = -1;
+ break;
+
+ // Rotate left 180°
+ case 3:
+ rotate = -180;
+ break;
+
+ // Flip vertical
+ case 4:
+ scaleY = -1;
+ break;
+
+ // Flip vertical and rotate right 90°
+ case 5:
+ rotate = 90;
+ scaleY = -1;
+ break;
+
+ // Rotate right 90°
+ case 6:
+ rotate = 90;
+ break;
+
+ // Flip horizontal and rotate right 90°
+ case 7:
+ rotate = 90;
+ scaleX = -1;
+ break;
+
+ // Rotate left 90°
+ case 8:
+ rotate = -90;
+ break;
+
+ default:
+ }
+
+ return {
+ rotate,
+ scaleX,
+ scaleY,
+ };
+}
diff --git a/library/cropperjs/test/css/main.css b/library/cropperjs/test/css/main.css
new file mode 100644
index 000000000..6a86d123c
--- /dev/null
+++ b/library/cropperjs/test/css/main.css
@@ -0,0 +1,9 @@
+.container {
+ max-width: 640px;
+ max-height: 360px;
+ margin: 20px auto;
+}
+
+.container > img {
+ max-width: 100%;
+}
diff --git a/library/cropperjs/test/events/crop.js b/library/cropperjs/test/events/crop.js
new file mode 100644
index 000000000..1f769cf60
--- /dev/null
+++ b/library/cropperjs/test/events/crop.js
@@ -0,0 +1,21 @@
+QUnit.test('events#crop', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(7);
+
+ image.addEventListener('crop', function (e) {
+ assert.ok(util.isNumber(e.detail.x));
+ assert.ok(util.isNumber(e.detail.y));
+ assert.ok(util.isNumber(e.detail.width));
+ assert.ok(util.isNumber(e.detail.height));
+ assert.ok(util.isNumber(e.detail.rotate));
+ assert.ok(util.isNumber(e.detail.scaleX));
+ assert.ok(util.isNumber(e.detail.scaleY));
+
+ done();
+ });
+
+ return new Cropper(image);
+});
diff --git a/library/cropperjs/test/events/cropend.js b/library/cropperjs/test/events/cropend.js
new file mode 100644
index 000000000..1f18fb435
--- /dev/null
+++ b/library/cropperjs/test/events/cropend.js
@@ -0,0 +1,24 @@
+QUnit.test('events#cropend', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ image.addEventListener('ready', function () {
+ var PointerEvent = window.PointerEvent;
+ var cropper = this.cropper;
+
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerdown' : 'mousedown');
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointermove' : 'mousemove');
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerup' : 'mouseup');
+
+ done();
+ });
+
+ image.addEventListener('cropend', function (e) {
+ assert.strictEqual(e.detail.action, 'crop');
+ });
+
+ return new Cropper(image);
+});
diff --git a/library/cropperjs/test/events/cropmove.js b/library/cropperjs/test/events/cropmove.js
new file mode 100644
index 000000000..c695b7fdd
--- /dev/null
+++ b/library/cropperjs/test/events/cropmove.js
@@ -0,0 +1,24 @@
+QUnit.test('events#cropmove', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ image.addEventListener('ready', function () {
+ var PointerEvent = window.PointerEvent;
+ var cropper = this.cropper;
+
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerdown' : 'mousedown');
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointermove' : 'mousemove');
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerup' : 'mouseup');
+
+ done();
+ });
+
+ image.addEventListener('cropmove', function (e) {
+ assert.strictEqual(e.detail.action, 'crop');
+ });
+
+ return new Cropper(image);
+});
diff --git a/library/cropperjs/test/events/cropstart.js b/library/cropperjs/test/events/cropstart.js
new file mode 100644
index 000000000..7d9b597a0
--- /dev/null
+++ b/library/cropperjs/test/events/cropstart.js
@@ -0,0 +1,56 @@
+QUnit.test('events#cropstart', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ image.addEventListener('ready', function () {
+ var PointerEvent = window.PointerEvent;
+ var cropper = this.cropper;
+
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerdown' : 'mousedown');
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerup' : 'mouseup');
+
+ done();
+ });
+
+ image.addEventListener('cropstart', function (e) {
+ assert.strictEqual(e.detail.action, 'crop');
+ });
+
+ return new Cropper(image);
+});
+
+QUnit.test('events#cropstart: default prevented', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(0);
+
+ image.addEventListener('ready', function () {
+ var PointerEvent = window.PointerEvent;
+ var cropper = this.cropper;
+
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerdown' : 'mousedown');
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointermove' : 'mousemove');
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerup' : 'mouseup');
+
+ done();
+ });
+
+ image.addEventListener('cropstart', function (e) {
+ e.preventDefault();
+ });
+
+ image.addEventListener('cropmove', function () {
+ assert.ok(false);
+ });
+
+ image.addEventListener('cropend', function () {
+ assert.ok(false);
+ });
+
+ return new Cropper(image);
+});
diff --git a/library/cropperjs/test/events/ready.js b/library/cropperjs/test/events/ready.js
new file mode 100644
index 000000000..fbec2ff0c
--- /dev/null
+++ b/library/cropperjs/test/events/ready.js
@@ -0,0 +1,15 @@
+QUnit.test('events#ready', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ image.addEventListener('ready', function () {
+ assert.ok(true);
+
+ done();
+ });
+
+ return new Cropper(image);
+});
diff --git a/library/cropperjs/test/events/zoom.js b/library/cropperjs/test/events/zoom.js
new file mode 100644
index 000000000..99fda34b5
--- /dev/null
+++ b/library/cropperjs/test/events/zoom.js
@@ -0,0 +1,46 @@
+QUnit.test('events#zoom', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(3);
+
+ image.addEventListener('ready', function () {
+ var cropper = this.cropper;
+
+ cropper.zoom(0.1);
+
+ done();
+ });
+
+ image.addEventListener('zoom', function (e) {
+ assert.ok(e.detail.ratio > 0);
+ assert.ok(e.detail.oldRatio > 0);
+ assert.ok(e.detail.ratio > e.detail.oldRatio);
+ });
+
+ return new Cropper(image);
+});
+
+QUnit.test('events#zoom: default prevented', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ image.addEventListener('ready', function () {
+ var cropper = this.cropper;
+ var canvasData = cropper.getCanvasData();
+
+ assert.deepEqual(cropper.zoom(0.1).getCanvasData(), canvasData);
+
+ done();
+ });
+
+ image.addEventListener('zoom', function (e) {
+ e.preventDefault();
+ });
+
+ return new Cropper(image);
+});
diff --git a/library/cropperjs/test/index.html b/library/cropperjs/test/index.html
new file mode 100644
index 000000000..bdcaf6b21
--- /dev/null
+++ b/library/cropperjs/test/index.html
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+ Cropper.js
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/library/cropperjs/test/js/main.js b/library/cropperjs/test/js/main.js
new file mode 100644
index 000000000..79fda799f
--- /dev/null
+++ b/library/cropperjs/test/js/main.js
@@ -0,0 +1,74 @@
+window.Util = {
+ isNumber: function (n) {
+ return typeof n === 'number' && !isNaN(n);
+ },
+ isFunction: function (fn) {
+ return typeof fn === 'function';
+ },
+ hasClass: function (element, className) {
+ return element.classList.contains(className);
+ },
+ getByClass: function (element, className) {
+ return element.getElementsByClassName ?
+ element.getElementsByClassName(className) :
+ element.querySelectorAll('.' + className);
+ },
+ createImage: function (attrs) {
+ var container = document.createElement('div');
+ var image = new Image();
+ var attr;
+
+ if (typeof attrs !== 'object') {
+ attrs = {};
+ }
+
+ if (!attrs.src) {
+ attrs.src = '../docs/images/picture.jpg';
+ }
+
+ for (attr in attrs) {
+ if (attrs.hasOwnProperty(attr)) {
+ image[attr] = attrs[attr];
+ }
+ }
+
+ container.className = 'container';
+ container.appendChild(image);
+ document.body.appendChild(container);
+
+ return image;
+ },
+ dispatchEvent: function (element, type, data) {
+ var event;
+
+ if (element.dispatchEvent) {
+ // Event and CustomEvent on IE9-11 are global objects, not constructors
+ if (typeof Event === 'function' && typeof CustomEvent === 'function') {
+ if (!data) {
+ event = new Event(type, {
+ bubbles: true,
+ cancelable: true
+ });
+ } else {
+ event = new CustomEvent(type, {
+ detail: data,
+ bubbles: true,
+ cancelable: true
+ });
+ }
+ } else if (!data) {
+ event = document.createEvent('Event');
+ event.initEvent(type, true, true);
+ } else {
+ event = document.createEvent('CustomEvent');
+ event.initCustomEvent(type, true, true, data);
+ }
+
+ // IE9+
+ return element.dispatchEvent(event);
+ } else if (element.fireEvent) {
+ // IE6-10 (native events only)
+ return element.fireEvent('on' + type);
+ }
+ }
+};
diff --git a/library/cropperjs/test/methods/clear.js b/library/cropperjs/test/methods/clear.js
new file mode 100644
index 000000000..6510ebad2
--- /dev/null
+++ b/library/cropperjs/test/methods/clear.js
@@ -0,0 +1,29 @@
+QUnit.test('methods#clear', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(4);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+
+ cropper.clear();
+ assert.notOk(cropper.cropped);
+ assert.deepEqual(cropper.getData(), {
+ x: 0,
+ y: 0,
+ width: 0,
+ height: 0,
+ rotate: 0,
+ scaleX: 1,
+ scaleY: 1
+ });
+ assert.deepEqual(cropper.getCropBoxData(), {});
+ assert.ok(util.hasClass(cropper.cropBox, 'cropper-hidden'));
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/crop.js b/library/cropperjs/test/methods/crop.js
new file mode 100644
index 000000000..e4ae679f1
--- /dev/null
+++ b/library/cropperjs/test/methods/crop.js
@@ -0,0 +1,24 @@
+QUnit.test('methods#crop', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(4);
+
+ return new Cropper(image, {
+ autoCrop: false,
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.notOk(cropper.cropped);
+ assert.ok(util.hasClass(cropper.cropBox, 'cropper-hidden'));
+
+ cropper.crop();
+ assert.ok(cropper.cropped);
+ assert.notOk(util.hasClass(cropper.cropBox, 'cropper-hidden'));
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/destroy.js b/library/cropperjs/test/methods/destroy.js
new file mode 100644
index 000000000..cb65e0696
--- /dev/null
+++ b/library/cropperjs/test/methods/destroy.js
@@ -0,0 +1,22 @@
+QUnit.test('methods#destroy', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(4);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.ok(typeof cropper === 'object');
+ assert.ok(util.hasClass(image, 'cropper-hidden'));
+
+ cropper.destroy();
+ assert.ok(typeof this.cropper === 'undefined');
+ assert.notOk(util.hasClass(image, 'cropper-hidden'));
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/disable.js b/library/cropperjs/test/methods/disable.js
new file mode 100644
index 000000000..c87f7aa91
--- /dev/null
+++ b/library/cropperjs/test/methods/disable.js
@@ -0,0 +1,60 @@
+QUnit.test('methods#disable', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(11);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var options = cropper.options;
+ var cropBoxData;
+ var canvasData;
+ var imageData;
+ var action;
+
+ cropper.disable();
+ assert.ok(cropper.disabled);
+ assert.ok(util.hasClass(cropper.cropper, 'cropper-disabled'));
+
+ cropBoxData = cropper.getCropBoxData();
+ cropper.clear();
+ assert.deepEqual(cropper.getCropBoxData(), cropBoxData);
+
+ imageData = cropper.getImageData();
+ cropper.move(10, 10);
+ assert.deepEqual(cropper.getImageData(), imageData);
+
+ cropper.zoom(0.5);
+ assert.strictEqual(cropper.getImageData().ratio, imageData.ratio);
+
+ cropper.rotate(15);
+ assert.strictEqual(cropper.getImageData().rotate, imageData.rotate);
+
+ cropper.scale(-1);
+ assert.strictEqual(cropper.getImageData().scaleX, imageData.scaleX);
+
+ canvasData = cropper.getCanvasData();
+ cropper.setCanvasData({
+ width: canvasData.width - 160
+ });
+ assert.deepEqual(cropper.getCanvasData(), canvasData);
+
+ cropBoxData = cropper.getCropBoxData();
+ cropper.setCropBoxData({
+ height: cropBoxData.height - 90
+ });
+ assert.deepEqual(cropper.getCropBoxData(), cropBoxData);
+
+ cropper.setAspectRatio(0.618);
+ assert.ok(isNaN(options.aspectRatio));
+
+ action = cropper.dragBox.dataset.action;
+ cropper.setDragMode('none');
+ assert.strictEqual(cropper.dragBox.dataset.action, action);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/enable.js b/library/cropperjs/test/methods/enable.js
new file mode 100644
index 000000000..ebd5b9529
--- /dev/null
+++ b/library/cropperjs/test/methods/enable.js
@@ -0,0 +1,23 @@
+QUnit.test('methods#enable', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(4);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+
+ cropper.disable();
+ assert.ok(cropper.disabled);
+ assert.ok(util.hasClass(cropper.cropper, 'cropper-disabled'));
+
+ cropper.enable();
+ assert.notOk(cropper.disabled);
+ assert.notOk(util.hasClass(cropper.cropper, 'cropper-disabled'));
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/getCanvasData.js b/library/cropperjs/test/methods/getCanvasData.js
new file mode 100644
index 000000000..60d96af4e
--- /dev/null
+++ b/library/cropperjs/test/methods/getCanvasData.js
@@ -0,0 +1,23 @@
+QUnit.test('methods#getCanvasData', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(6);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var canvasData = cropper.getCanvasData();
+
+ assert.ok(util.isNumber(canvasData.left));
+ assert.ok(util.isNumber(canvasData.top));
+ assert.ok(util.isNumber(canvasData.width));
+ assert.ok(util.isNumber(canvasData.height));
+ assert.ok(util.isNumber(canvasData.naturalWidth));
+ assert.ok(util.isNumber(canvasData.naturalHeight));
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/getContainerData.js b/library/cropperjs/test/methods/getContainerData.js
new file mode 100644
index 000000000..094421ba0
--- /dev/null
+++ b/library/cropperjs/test/methods/getContainerData.js
@@ -0,0 +1,19 @@
+QUnit.test('methods#getContainerData', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var containerData = cropper.getContainerData();
+
+ assert.ok(util.isNumber(containerData.width));
+ assert.ok(util.isNumber(containerData.height));
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/getCropBoxData.js b/library/cropperjs/test/methods/getCropBoxData.js
new file mode 100644
index 000000000..844c7953e
--- /dev/null
+++ b/library/cropperjs/test/methods/getCropBoxData.js
@@ -0,0 +1,21 @@
+QUnit.test('methods#getCropBoxData', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(4);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var cropBoxData = cropper.getCropBoxData();
+
+ assert.ok(util.isNumber(cropBoxData.left));
+ assert.ok(util.isNumber(cropBoxData.top));
+ assert.ok(util.isNumber(cropBoxData.width));
+ assert.ok(util.isNumber(cropBoxData.height));
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/getCroppedCanvas.js b/library/cropperjs/test/methods/getCroppedCanvas.js
new file mode 100644
index 000000000..4117497a5
--- /dev/null
+++ b/library/cropperjs/test/methods/getCroppedCanvas.js
@@ -0,0 +1,33 @@
+QUnit.test('methods#getCroppedCanvas', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(7);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var canvas = cropper.getCroppedCanvas({
+ width: 160,
+ height: 90
+ });
+ var pixelData;
+
+ assert.ok(canvas instanceof HTMLCanvasElement);
+ assert.strictEqual(canvas.width, 160);
+ assert.strictEqual(canvas.height, 90);
+
+ canvas = cropper.rotate(90).getCroppedCanvas({
+ fillColor: '#010101'
+ });
+ pixelData = canvas.getContext('2d').getImageData(0, 0, 1, 1).data;
+ assert.strictEqual(pixelData[0], 1, 'red is 1');
+ assert.strictEqual(pixelData[1], 1, 'green is 1');
+ assert.strictEqual(pixelData[2], 1, 'blue is 1');
+ assert.strictEqual(pixelData[3], 255, 'color is opaque');
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/getData.js b/library/cropperjs/test/methods/getData.js
new file mode 100644
index 000000000..9c519eb7f
--- /dev/null
+++ b/library/cropperjs/test/methods/getData.js
@@ -0,0 +1,46 @@
+QUnit.test('methods#getData', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(7);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var data = cropper.getData();
+
+ assert.ok(util.isNumber(data.x));
+ assert.ok(util.isNumber(data.y));
+ assert.ok(util.isNumber(data.width));
+ assert.ok(util.isNumber(data.height));
+ assert.ok(util.isNumber(data.rotate));
+ assert.ok(util.isNumber(data.scaleX));
+ assert.ok(util.isNumber(data.scaleY));
+
+ done();
+ }
+ });
+});
+
+QUnit.test('methods#getData: rounded', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(4);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var data = cropper.getData(true);
+
+ assert.ok(data.x % 1 === 0);
+ assert.ok(data.y % 1 === 0);
+ assert.ok(data.width % 1 === 0);
+ assert.ok(data.height % 1 === 0);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/getImageData.js b/library/cropperjs/test/methods/getImageData.js
new file mode 100644
index 000000000..bd6e1941d
--- /dev/null
+++ b/library/cropperjs/test/methods/getImageData.js
@@ -0,0 +1,31 @@
+QUnit.test('methods#getImageData', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(10);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var imageData = cropper.getImageData();
+
+ assert.ok(util.isNumber(imageData.naturalWidth));
+ assert.ok(util.isNumber(imageData.naturalHeight));
+ assert.ok(util.isNumber(imageData.aspectRatio));
+ assert.ok(util.isNumber(imageData.left));
+ assert.ok(util.isNumber(imageData.top));
+ assert.ok(util.isNumber(imageData.width));
+ assert.ok(util.isNumber(imageData.height));
+
+ imageData = cropper.rotateTo(45).getImageData();
+ assert.strictEqual(imageData.rotate, 45);
+
+ imageData = cropper.scale(-1, -1).getImageData();
+ assert.strictEqual(imageData.scaleX, -1);
+ assert.strictEqual(imageData.scaleY, -1);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/move.js b/library/cropperjs/test/methods/move.js
new file mode 100644
index 000000000..c2ead8412
--- /dev/null
+++ b/library/cropperjs/test/methods/move.js
@@ -0,0 +1,20 @@
+QUnit.test('methods#move', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var canvasData = cropper.getCanvasData();
+ var changedCanvasData = cropper.move(1, 1).getCanvasData();
+
+ assert.strictEqual(changedCanvasData.left, canvasData.left + 1);
+ assert.strictEqual(changedCanvasData.top, canvasData.top + 1);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/moveTo.js b/library/cropperjs/test/methods/moveTo.js
new file mode 100644
index 000000000..e8bf0eebd
--- /dev/null
+++ b/library/cropperjs/test/methods/moveTo.js
@@ -0,0 +1,19 @@
+QUnit.test('methods#moveTo', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var canvasData = cropper.moveTo(0, 0).getCanvasData();
+
+ assert.strictEqual(canvasData.left, 0);
+ assert.strictEqual(canvasData.top, 0);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/replace.js b/library/cropperjs/test/methods/replace.js
new file mode 100644
index 000000000..3fc8fe0b6
--- /dev/null
+++ b/library/cropperjs/test/methods/replace.js
@@ -0,0 +1,23 @@
+QUnit.test('methods#replace', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+
+ cropper.options.ready = function () {
+ assert.notOk(cropper.cropped);
+ cropper.crop();
+ assert.ok(cropper.cropped);
+ done();
+ };
+
+ cropper.options.autoCrop = false;
+ cropper.replace('../docs/images/picture-2.jpg');
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/reset.js b/library/cropperjs/test/methods/reset.js
new file mode 100644
index 000000000..3e047394c
--- /dev/null
+++ b/library/cropperjs/test/methods/reset.js
@@ -0,0 +1,35 @@
+QUnit.test('methods#reset', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(4);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var canvasData = cropper.getCanvasData();
+ var cropBoxData = cropper.getCropBoxData();
+
+ cropper.setCanvasData({
+ top: canvasData.top + 10,
+ width: canvasData.width - 10
+ });
+
+ assert.notDeepEqual(cropper.getCanvasData(), canvasData);
+
+ cropper.setCropBoxData({
+ left: cropBoxData.left + 10,
+ height: cropBoxData.height - 10
+ });
+
+ assert.notDeepEqual(cropper.getCropBoxData(), cropBoxData);
+
+ cropper.reset();
+ assert.deepEqual(cropper.getCanvasData(), canvasData);
+ assert.deepEqual(cropper.getCropBoxData(), cropBoxData);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/rotate.js b/library/cropperjs/test/methods/rotate.js
new file mode 100644
index 000000000..749096f0b
--- /dev/null
+++ b/library/cropperjs/test/methods/rotate.js
@@ -0,0 +1,19 @@
+QUnit.test('methods#rotate', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(3);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.strictEqual(cropper.rotate(360).getImageData().rotate, 0);
+ assert.strictEqual(cropper.rotate(90).getImageData().rotate, 90);
+ assert.strictEqual(cropper.rotate(-180).getImageData().rotate, -90);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/rotateTo.js b/library/cropperjs/test/methods/rotateTo.js
new file mode 100644
index 000000000..323431e76
--- /dev/null
+++ b/library/cropperjs/test/methods/rotateTo.js
@@ -0,0 +1,20 @@
+QUnit.test('methods#rotateTo', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(4);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.strictEqual(cropper.rotateTo(360).getImageData().rotate, 0);
+ assert.strictEqual(cropper.rotateTo(90).getImageData().rotate, 90);
+ assert.strictEqual(cropper.rotateTo(0).getImageData().rotate, 0);
+ assert.strictEqual(cropper.rotateTo(-180).getImageData().rotate, -180);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/scale.js b/library/cropperjs/test/methods/scale.js
new file mode 100644
index 000000000..be1caa589
--- /dev/null
+++ b/library/cropperjs/test/methods/scale.js
@@ -0,0 +1,19 @@
+QUnit.test('methods#scale', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var imageData = cropper.scale(-1, -1).getImageData();
+
+ assert.strictEqual(imageData.scaleX, -1);
+ assert.strictEqual(imageData.scaleY, -1);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/scaleX.js b/library/cropperjs/test/methods/scaleX.js
new file mode 100644
index 000000000..c799df58d
--- /dev/null
+++ b/library/cropperjs/test/methods/scaleX.js
@@ -0,0 +1,18 @@
+QUnit.test('methods#scaleX', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var imageData = cropper.scaleX(-1).getImageData();
+
+ assert.strictEqual(imageData.scaleX, -1);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/scaleY.js b/library/cropperjs/test/methods/scaleY.js
new file mode 100644
index 000000000..026b93a1f
--- /dev/null
+++ b/library/cropperjs/test/methods/scaleY.js
@@ -0,0 +1,18 @@
+QUnit.test('methods#scaleY', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var imageData = cropper.scaleY(-1).getImageData();
+
+ assert.strictEqual(imageData.scaleY, -1);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/setAspectRatio.js b/library/cropperjs/test/methods/setAspectRatio.js
new file mode 100644
index 000000000..ddf46798d
--- /dev/null
+++ b/library/cropperjs/test/methods/setAspectRatio.js
@@ -0,0 +1,20 @@
+QUnit.test('methods#setAspectRatio', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var options = cropper.options;
+
+ assert.ok(isNaN(options.aspectRatio));
+ cropper.setAspectRatio(1);
+ assert.strictEqual(options.aspectRatio, 1);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/setCanvasData.js b/library/cropperjs/test/methods/setCanvasData.js
new file mode 100644
index 000000000..e8f6511dc
--- /dev/null
+++ b/library/cropperjs/test/methods/setCanvasData.js
@@ -0,0 +1,34 @@
+QUnit.test('methods#setCanvasData', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(6);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var canvasData = cropper.getCanvasData();
+ var changedCanvasData = cropper.setCanvasData({
+ left: 16,
+ top: 9
+ }).getCanvasData();
+
+ assert.notStrictEqual(changedCanvasData.left, canvasData.left);
+ assert.notStrictEqual(changedCanvasData.top, canvasData.top);
+ assert.strictEqual(changedCanvasData.width, canvasData.width);
+ assert.strictEqual(changedCanvasData.height, canvasData.height);
+
+ canvasData = cropper.getCanvasData();
+ changedCanvasData = cropper.setCanvasData({
+ width: 320,
+ height: 180
+ }).getCanvasData();
+
+ assert.notStrictEqual(changedCanvasData.width, canvasData.width);
+ assert.notStrictEqual(changedCanvasData.height, canvasData.height);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/setCropBoxData.js b/library/cropperjs/test/methods/setCropBoxData.js
new file mode 100644
index 000000000..e78767cfc
--- /dev/null
+++ b/library/cropperjs/test/methods/setCropBoxData.js
@@ -0,0 +1,36 @@
+QUnit.test('methods#setCropBoxData', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(8);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var cropBoxData = cropper.getCropBoxData();
+ var changedCropBoxData = cropper.setCropBoxData({
+ left: 16,
+ top: 9
+ }).getCropBoxData();
+
+ assert.notStrictEqual(changedCropBoxData.left, cropBoxData.left);
+ assert.notStrictEqual(changedCropBoxData.top, cropBoxData.top);
+ assert.strictEqual(changedCropBoxData.width, cropBoxData.width);
+ assert.strictEqual(changedCropBoxData.height, cropBoxData.height);
+
+ cropBoxData = cropper.getCropBoxData();
+ changedCropBoxData = cropper.setCropBoxData({
+ width: 320,
+ height: 180
+ }).getCropBoxData();
+
+ assert.strictEqual(changedCropBoxData.left, cropBoxData.left);
+ assert.strictEqual(changedCropBoxData.top, cropBoxData.top);
+ assert.notStrictEqual(changedCropBoxData.width, cropBoxData.width);
+ assert.notStrictEqual(changedCropBoxData.height, cropBoxData.height);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/setData.js b/library/cropperjs/test/methods/setData.js
new file mode 100644
index 000000000..4e1360f09
--- /dev/null
+++ b/library/cropperjs/test/methods/setData.js
@@ -0,0 +1,36 @@
+QUnit.test('methods#setData', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(8);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var data = cropper.getData();
+ var changedData = cropper.setData({
+ x: 16,
+ y: 9
+ }).getData();
+
+ assert.notStrictEqual(changedData.x, data.x);
+ assert.notStrictEqual(changedData.y, data.y);
+ assert.strictEqual(changedData.width, data.width);
+ assert.strictEqual(changedData.height, data.height);
+
+ data = cropper.getData();
+ changedData = cropper.setData({
+ width: 320,
+ height: 180
+ }).getData();
+
+ assert.strictEqual(changedData.x, data.x);
+ assert.strictEqual(changedData.y, data.y);
+ assert.notStrictEqual(changedData.width, data.width);
+ assert.notStrictEqual(changedData.height, data.height);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/setDragMode.js b/library/cropperjs/test/methods/setDragMode.js
new file mode 100644
index 000000000..1b611af9b
--- /dev/null
+++ b/library/cropperjs/test/methods/setDragMode.js
@@ -0,0 +1,27 @@
+QUnit.test('methods#setDragMode', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(4);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var dragBox = cropper.dragBox;
+
+ assert.strictEqual(dragBox.dataset.action, 'crop');
+
+ cropper.setDragMode('move');
+ assert.strictEqual(dragBox.dataset.action, 'move');
+
+ cropper.setDragMode('crop');
+ assert.strictEqual(dragBox.dataset.action, 'crop');
+
+ cropper.setDragMode('none');
+ assert.strictEqual(dragBox.dataset.action, 'none');
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/zoom.js b/library/cropperjs/test/methods/zoom.js
new file mode 100644
index 000000000..70a1a763a
--- /dev/null
+++ b/library/cropperjs/test/methods/zoom.js
@@ -0,0 +1,20 @@
+QUnit.test('methods#zoom', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var canvasData = cropper.getCanvasData();
+ var changedCanvasData = cropper.zoom(0.1).getCanvasData();
+
+ assert.ok(changedCanvasData.width > canvasData.width);
+ assert.ok(changedCanvasData.height > canvasData.height);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/methods/zoomTo.js b/library/cropperjs/test/methods/zoomTo.js
new file mode 100644
index 000000000..dd9e81760
--- /dev/null
+++ b/library/cropperjs/test/methods/zoomTo.js
@@ -0,0 +1,21 @@
+QUnit.test('methods#zoomTo', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(3);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var imageData = cropper.zoomTo(1).getImageData();
+ var canvasData = cropper.getCanvasData();
+
+ assert.strictEqual(imageData.width, imageData.naturalWidth);
+ assert.strictEqual(canvasData.width, canvasData.naturalWidth);
+ assert.strictEqual(canvasData.naturalWidth, imageData.naturalWidth);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/aspectRatio.js b/library/cropperjs/test/options/aspectRatio.js
new file mode 100644
index 000000000..d7ba89401
--- /dev/null
+++ b/library/cropperjs/test/options/aspectRatio.js
@@ -0,0 +1,39 @@
+QUnit.test('options#aspectRatio: NaN', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ // aspectRatio: NaN,
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.ok(isNaN(cropper.options.aspectRatio));
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#aspectRatio: 1', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ aspectRatio: 1,
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.strictEqual(cropper.options.aspectRatio, 1);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/autoCrop.js b/library/cropperjs/test/options/autoCrop.js
new file mode 100644
index 000000000..f010966eb
--- /dev/null
+++ b/library/cropperjs/test/options/autoCrop.js
@@ -0,0 +1,39 @@
+QUnit.test('options#autoCrop: true', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ // autoCrop: true,
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.ok(cropper.cropped);
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#autoCrop: false', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ autoCrop: false,
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.notOk(cropper.cropped);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/background.js b/library/cropperjs/test/options/background.js
new file mode 100644
index 000000000..21dbb8b12
--- /dev/null
+++ b/library/cropperjs/test/options/background.js
@@ -0,0 +1,40 @@
+QUnit.test('options#background: true', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ // background: true,
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.ok(util.hasClass(cropper.cropper, 'cropper-bg'));
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#background: false', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ background: false,
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.notOk(util.hasClass(cropper.cropper, 'cropper-bg'));
+
+ done();
+ }
+ });
+
+});
diff --git a/library/cropperjs/test/options/center.js b/library/cropperjs/test/options/center.js
new file mode 100644
index 000000000..5d45eb021
--- /dev/null
+++ b/library/cropperjs/test/options/center.js
@@ -0,0 +1,41 @@
+QUnit.test('options#center: true', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ // center: true,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var center = util.getByClass(cropper.cropBox, 'cropper-center');
+
+ assert.notOk(util.hasClass(center[0], 'cropper-hidden'));
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#center: false', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ center: false,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var center = util.getByClass(cropper.cropBox, 'cropper-center');
+
+ assert.ok(util.hasClass(center[0], 'cropper-hidden'));
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/checkCrossOrigin.js b/library/cropperjs/test/options/checkCrossOrigin.js
new file mode 100644
index 000000000..86fde8f6f
--- /dev/null
+++ b/library/cropperjs/test/options/checkCrossOrigin.js
@@ -0,0 +1,67 @@
+QUnit.test('options#checkCrossOrigin: true', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage({
+ src: 'https://fengyuanchen.github.io/cropperjs/images/picture.jpg'
+ });
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ // checkCrossOrigin: true,
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.strictEqual(cropper.image.crossOrigin, 'anonymous');
+ assert.ok(cropper.image.src.indexOf('timestamp') >= 0);
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#checkCrossOrigin: false', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage({
+ src: 'https://fengyuanchen.github.io/cropperjs/images/picture.jpg'
+ });
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ checkCrossOrigin: false,
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.notStrictEqual(cropper.image.crossOrigin, 'anonymous');
+ assert.ok(cropper.image.src.indexOf('timestamp') < 0);
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#checkCrossOrigin: exists crossOrigin attribute', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage({
+ src: 'https://fengyuanchen.github.io/cropperjs/images/picture.jpg',
+ crossOrigin: 'anonymous'
+ });
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.strictEqual(cropper.image.crossOrigin, 'anonymous');
+ assert.ok(cropper.image.src.indexOf('timestamp') < 0);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/checkOrientation.js b/library/cropperjs/test/options/checkOrientation.js
new file mode 100644
index 000000000..0fe548404
--- /dev/null
+++ b/library/cropperjs/test/options/checkOrientation.js
@@ -0,0 +1,43 @@
+QUnit.test('options#checkOrientation: true', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage({
+ src: '../docs/images/picture-3.jpg'
+ });
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ // checkOrientation: true,
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.notStrictEqual(cropper.getData().rotate, 0);
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#checkOrientation: false', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage({
+ src: '../docs/images/picture-3.jpg'
+ });
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ checkOrientation: false,
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.strictEqual(cropper.getData().rotate, 0);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/crop.js b/library/cropperjs/test/options/crop.js
new file mode 100644
index 000000000..a4b48585e
--- /dev/null
+++ b/library/cropperjs/test/options/crop.js
@@ -0,0 +1,21 @@
+QUnit.test('options#crop', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(7);
+
+ return new Cropper(image, {
+ crop: function (e) {
+ assert.ok(util.isNumber(e.detail.x));
+ assert.ok(util.isNumber(e.detail.y));
+ assert.ok(util.isNumber(e.detail.width));
+ assert.ok(util.isNumber(e.detail.height));
+ assert.ok(util.isNumber(e.detail.rotate));
+ assert.ok(util.isNumber(e.detail.scaleX));
+ assert.ok(util.isNumber(e.detail.scaleY));
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/cropBoxMovable.js b/library/cropperjs/test/options/cropBoxMovable.js
new file mode 100644
index 000000000..d5d3e1d7d
--- /dev/null
+++ b/library/cropperjs/test/options/cropBoxMovable.js
@@ -0,0 +1,41 @@
+QUnit.test('options#cropBoxMovable: true', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ // cropBoxMovable: true,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var face = util.getByClass(cropper.cropBox, 'cropper-face');
+
+ assert.strictEqual(face[0].dataset.action, 'all');
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#cropBoxMovable: false', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ cropBoxMovable: false,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var face = util.getByClass(cropper.cropBox, 'cropper-face');
+
+ assert.strictEqual(face[0].dataset.action, cropper.options.dragMode);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/cropBoxResizable.js b/library/cropperjs/test/options/cropBoxResizable.js
new file mode 100644
index 000000000..37093642b
--- /dev/null
+++ b/library/cropperjs/test/options/cropBoxResizable.js
@@ -0,0 +1,65 @@
+QUnit.test('options#cropBoxResizable: true', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(12);
+
+ return new Cropper(image, {
+ // cropBoxResizable: true,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var line = util.getByClass(cropper.cropBox, 'cropper-line');
+ var point = util.getByClass(cropper.cropBox, 'cropper-point');
+
+ assert.notOk(util.hasClass(line[0], 'cropper-hidden'));
+ assert.notOk(util.hasClass(line[1], 'cropper-hidden'));
+ assert.notOk(util.hasClass(line[2], 'cropper-hidden'));
+ assert.notOk(util.hasClass(line[3], 'cropper-hidden'));
+ assert.notOk(util.hasClass(point[0], 'cropper-hidden'));
+ assert.notOk(util.hasClass(point[1], 'cropper-hidden'));
+ assert.notOk(util.hasClass(point[2], 'cropper-hidden'));
+ assert.notOk(util.hasClass(point[3], 'cropper-hidden'));
+ assert.notOk(util.hasClass(point[4], 'cropper-hidden'));
+ assert.notOk(util.hasClass(point[5], 'cropper-hidden'));
+ assert.notOk(util.hasClass(point[6], 'cropper-hidden'));
+ assert.notOk(util.hasClass(point[7], 'cropper-hidden'));
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#cropBoxResizable: false', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(12);
+
+ return new Cropper(image, {
+ cropBoxResizable: false,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var line = util.getByClass(cropper.cropBox, 'cropper-line');
+ var point = util.getByClass(cropper.cropBox, 'cropper-point');
+
+ assert.ok(util.hasClass(line[0], 'cropper-hidden'));
+ assert.ok(util.hasClass(line[1], 'cropper-hidden'));
+ assert.ok(util.hasClass(line[2], 'cropper-hidden'));
+ assert.ok(util.hasClass(line[3], 'cropper-hidden'));
+ assert.ok(util.hasClass(point[0], 'cropper-hidden'));
+ assert.ok(util.hasClass(point[1], 'cropper-hidden'));
+ assert.ok(util.hasClass(point[2], 'cropper-hidden'));
+ assert.ok(util.hasClass(point[3], 'cropper-hidden'));
+ assert.ok(util.hasClass(point[4], 'cropper-hidden'));
+ assert.ok(util.hasClass(point[5], 'cropper-hidden'));
+ assert.ok(util.hasClass(point[6], 'cropper-hidden'));
+ assert.ok(util.hasClass(point[7], 'cropper-hidden'));
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/cropend.js b/library/cropperjs/test/options/cropend.js
new file mode 100644
index 000000000..abfe815c0
--- /dev/null
+++ b/library/cropperjs/test/options/cropend.js
@@ -0,0 +1,24 @@
+QUnit.test('options#cropend', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ ready: function () {
+ var PointerEvent = window.PointerEvent;
+ var cropper = this.cropper;
+
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerdown' : 'mousedown');
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointermove' : 'mousemove');
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerup' : 'mouseup');
+
+ done();
+ },
+
+ cropend: function (e) {
+ assert.strictEqual(e.detail.action, 'crop');
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/cropmove.js b/library/cropperjs/test/options/cropmove.js
new file mode 100644
index 000000000..fa20f4011
--- /dev/null
+++ b/library/cropperjs/test/options/cropmove.js
@@ -0,0 +1,24 @@
+QUnit.test('options#cropmove', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ ready: function () {
+ var PointerEvent = window.PointerEvent;
+ var cropper = this.cropper;
+
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerdown' : 'mousedown');
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointermove' : 'mousemove');
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerup' : 'mouseup');
+
+ done();
+ },
+
+ cropmove: function (e) {
+ assert.strictEqual(e.detail.action, 'crop');
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/cropstart.js b/library/cropperjs/test/options/cropstart.js
new file mode 100644
index 000000000..f547269cd
--- /dev/null
+++ b/library/cropperjs/test/options/cropstart.js
@@ -0,0 +1,56 @@
+QUnit.test('options#cropstart', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ ready: function () {
+ var PointerEvent = window.PointerEvent;
+ var cropper = this.cropper;
+
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerdown' : 'mousedown');
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerup' : 'mouseup');
+
+ done();
+ },
+
+ cropstart: function (e) {
+ assert.strictEqual(e.detail.action, 'crop');
+ }
+ });
+});
+
+QUnit.test('options#cropstart: default prevented', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(0);
+
+ return new Cropper(image, {
+ ready: function () {
+ var PointerEvent = window.PointerEvent;
+ var cropper = this.cropper;
+
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerdown' : 'mousedown');
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointermove' : 'mousemove');
+ util.dispatchEvent(cropper.dragBox, PointerEvent ? 'pointerup' : 'mouseup');
+
+ done();
+ },
+
+ cropstart: function (e) {
+ e.preventDefault();
+ },
+
+ cropmove: function () {
+ assert.ok(false);
+ },
+
+ cropend: function () {
+ assert.ok(false);
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/data.js b/library/cropperjs/test/options/data.js
new file mode 100644
index 000000000..e9da6a4dd
--- /dev/null
+++ b/library/cropperjs/test/options/data.js
@@ -0,0 +1,35 @@
+QUnit.test('options#data', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+ var initialData = {
+ x: 360,
+ y: 450,
+ width: 640,
+ height: 360,
+ rotate: 45,
+ scaleX: -1,
+ scaleY: -1
+ };
+
+ assert.expect(7);
+
+ return new Cropper(image, {
+ data: initialData,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var data = cropper.getData(true);
+
+ assert.strictEqual(data.x, initialData.x);
+ assert.strictEqual(data.y, initialData.y);
+ assert.strictEqual(data.width, initialData.width);
+ assert.strictEqual(data.height, initialData.height);
+ assert.strictEqual(data.rotate, initialData.rotate);
+ assert.strictEqual(data.scaleX, initialData.scaleX);
+ assert.strictEqual(data.scaleY, initialData.scaleY);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/dragMode.js b/library/cropperjs/test/options/dragMode.js
new file mode 100644
index 000000000..57f31ff13
--- /dev/null
+++ b/library/cropperjs/test/options/dragMode.js
@@ -0,0 +1,60 @@
+QUnit.test('options#dragMode: crop', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ // dragMode: 'crop',
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.strictEqual(cropper.dragBox.dataset.action, 'crop');
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#dragMode: move', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ dragMode: 'move',
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.strictEqual(cropper.dragBox.dataset.action, 'move');
+
+ done();
+ }
+ });
+});
+
+
+QUnit.test('options#dragMode: none', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ dragMode: 'none',
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.strictEqual(cropper.dragBox.dataset.action, 'none');
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/guides.js b/library/cropperjs/test/options/guides.js
new file mode 100644
index 000000000..298c3ad3a
--- /dev/null
+++ b/library/cropperjs/test/options/guides.js
@@ -0,0 +1,43 @@
+QUnit.test('options#guides: true', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ // guides: true,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var dashed = util.getByClass(cropper.cropBox, 'cropper-dashed');
+
+ assert.notOk(util.hasClass(dashed[0], 'cropper-hidden'));
+ assert.notOk(util.hasClass(dashed[1], 'cropper-hidden'));
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#guides: false', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ guides: false,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var dashed = util.getByClass(cropper.cropBox, 'cropper-dashed');
+
+ assert.ok(util.hasClass(dashed[0], 'cropper-hidden'));
+ assert.ok(util.hasClass(dashed[1], 'cropper-hidden'));
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/highlight.js b/library/cropperjs/test/options/highlight.js
new file mode 100644
index 000000000..a1db4687f
--- /dev/null
+++ b/library/cropperjs/test/options/highlight.js
@@ -0,0 +1,41 @@
+QUnit.test('options#highlight: true', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ // highlight: true,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var face = util.getByClass(cropper.cropBox, 'cropper-face');
+
+ assert.notOk(util.hasClass(face[0], 'cropper-invisible'));
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#highlight: false', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ highlight: false,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var face = util.getByClass(cropper.cropBox, 'cropper-face');
+
+ assert.ok(util.hasClass(face[0], 'cropper-invisible'));
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/minCanvasHeight.js b/library/cropperjs/test/options/minCanvasHeight.js
new file mode 100644
index 000000000..c9745a9b1
--- /dev/null
+++ b/library/cropperjs/test/options/minCanvasHeight.js
@@ -0,0 +1,23 @@
+QUnit.test('options#minCanvasHeight', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+ var minCanvasHeight = 270;
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ minCanvasHeight: minCanvasHeight,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var canvasData = cropper.setCanvasData({
+ height: 180
+ }).getCanvasData();
+
+ assert.strictEqual(Math.round(canvasData.height), minCanvasHeight);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/minCanvasWidth.js b/library/cropperjs/test/options/minCanvasWidth.js
new file mode 100644
index 000000000..61601e4f9
--- /dev/null
+++ b/library/cropperjs/test/options/minCanvasWidth.js
@@ -0,0 +1,23 @@
+QUnit.test('options#minCanvasWidth', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+ var minCanvasWidth = 480;
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ minCanvasWidth: minCanvasWidth,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var canvasData = cropper.setCanvasData({
+ width: 320
+ }).getCanvasData();
+
+ assert.strictEqual(Math.round(canvasData.width), minCanvasWidth);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/minContainerHeight.js b/library/cropperjs/test/options/minContainerHeight.js
new file mode 100644
index 000000000..85d7a70ef
--- /dev/null
+++ b/library/cropperjs/test/options/minContainerHeight.js
@@ -0,0 +1,21 @@
+QUnit.test('options#minContainerHeight', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+ var minContainerHeight = 361;
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ minContainerHeight: minContainerHeight,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var containerData = cropper.getContainerData();
+
+ assert.strictEqual(Math.round(containerData.height), minContainerHeight);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/minContainerWidth.js b/library/cropperjs/test/options/minContainerWidth.js
new file mode 100644
index 000000000..2119cc96e
--- /dev/null
+++ b/library/cropperjs/test/options/minContainerWidth.js
@@ -0,0 +1,21 @@
+QUnit.test('options#minContainerWidth', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+ var minContainerWidth = 641;
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ minContainerWidth: minContainerWidth,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var containerData = cropper.getContainerData();
+
+ assert.strictEqual(Math.round(containerData.width), minContainerWidth);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/minCropBoxHeight.js b/library/cropperjs/test/options/minCropBoxHeight.js
new file mode 100644
index 000000000..ccf50aefe
--- /dev/null
+++ b/library/cropperjs/test/options/minCropBoxHeight.js
@@ -0,0 +1,23 @@
+QUnit.test('options#minCropBoxHeight', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+ var minCropBoxHeight = 150;
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ minCropBoxHeight: minCropBoxHeight,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var cropBoxData = cropper.setCropBoxData({
+ height: 100
+ }).getCropBoxData();
+
+ assert.strictEqual(Math.round(cropBoxData.height), minCropBoxHeight);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/minCropBoxWidth.js b/library/cropperjs/test/options/minCropBoxWidth.js
new file mode 100644
index 000000000..acde5c366
--- /dev/null
+++ b/library/cropperjs/test/options/minCropBoxWidth.js
@@ -0,0 +1,23 @@
+QUnit.test('options#minCropBoxWidth', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+ var minCropBoxWidth = 300;
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ minCropBoxWidth: minCropBoxWidth,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var cropBoxData = cropper.setCropBoxData({
+ width: 200
+ }).getCropBoxData();
+
+ assert.strictEqual(Math.round(cropBoxData.width), minCropBoxWidth);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/modal.js b/library/cropperjs/test/options/modal.js
new file mode 100644
index 000000000..7284cb264
--- /dev/null
+++ b/library/cropperjs/test/options/modal.js
@@ -0,0 +1,39 @@
+QUnit.test('options#modal: true', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ // modal: true,
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.ok(util.hasClass(cropper.dragBox, 'cropper-modal'));
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#modal: false', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ modal: false,
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.notOk(util.hasClass(cropper.dragBox, 'cropper-modal'));
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/movable.js b/library/cropperjs/test/options/movable.js
new file mode 100644
index 000000000..0e2c53506
--- /dev/null
+++ b/library/cropperjs/test/options/movable.js
@@ -0,0 +1,45 @@
+QUnit.test('options#movable: true', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ // movable: true,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var canvasData = cropper.getCanvasData();
+ var changedCanvasData = cropper.move(10, 10).getCanvasData();
+
+ assert.strictEqual(changedCanvasData.left, canvasData.left + 10);
+ assert.strictEqual(changedCanvasData.top, canvasData.top + 10);
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#movable: false', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ movable: false,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var canvasData = cropper.getCanvasData();
+ var changedCanvasData = cropper.move(10, 10).getCanvasData();
+
+ assert.strictEqual(changedCanvasData.left, canvasData.left);
+ assert.strictEqual(changedCanvasData.top, canvasData.top);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/ready.js b/library/cropperjs/test/options/ready.js
new file mode 100644
index 000000000..e09e8369c
--- /dev/null
+++ b/library/cropperjs/test/options/ready.js
@@ -0,0 +1,15 @@
+QUnit.test('options#ready', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ ready: function () {
+ assert.ok(true);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/rotatable.js b/library/cropperjs/test/options/rotatable.js
new file mode 100644
index 000000000..992e9362f
--- /dev/null
+++ b/library/cropperjs/test/options/rotatable.js
@@ -0,0 +1,39 @@
+QUnit.test('options#rotatable: true', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ // rotatable: true,
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.strictEqual(cropper.rotate(90).getImageData().rotate, 90);
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#rotatable: false', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ rotatable: false,
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ assert.strictEqual(cropper.rotate(90).getImageData().rotate, undefined);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/scalable.js b/library/cropperjs/test/options/scalable.js
new file mode 100644
index 000000000..c523eaf63
--- /dev/null
+++ b/library/cropperjs/test/options/scalable.js
@@ -0,0 +1,43 @@
+QUnit.test('options#scalable: true', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ // scalable: true,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var imageData = cropper.scale(-1, -1).getImageData();
+
+ assert.strictEqual(imageData.scaleX, -1);
+ assert.strictEqual(imageData.scaleY, -1);
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#scalable: false', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ scalable: false,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var imageData = cropper.scale(-1, -1).getImageData();
+
+ assert.strictEqual(imageData.scaleX, undefined);
+ assert.strictEqual(imageData.scaleY, undefined);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/toggleDragModeOnDblclick.js b/library/cropperjs/test/options/toggleDragModeOnDblclick.js
new file mode 100644
index 000000000..df64327b2
--- /dev/null
+++ b/library/cropperjs/test/options/toggleDragModeOnDblclick.js
@@ -0,0 +1,45 @@
+QUnit.test('options#toggleDragModeOnDblclick: true', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ // toggleDragModeOnDblclick: true,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var dragBox = cropper.dragBox;
+
+ util.dispatchEvent(dragBox, 'dblclick');
+ assert.ok(util.hasClass(dragBox, 'cropper-move'));
+ assert.strictEqual(dragBox.dataset.action, 'move');
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#toggleDragModeOnDblclick: false', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ toggleDragModeOnDblclick: false,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var dragBox = cropper.dragBox;
+
+ util.dispatchEvent(dragBox, 'dblclick');
+ assert.ok(util.hasClass(dragBox, 'cropper-crop'));
+ assert.strictEqual(dragBox.dataset.action, 'crop');
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/viewMode.js b/library/cropperjs/test/options/viewMode.js
new file mode 100644
index 000000000..e39ec5fc1
--- /dev/null
+++ b/library/cropperjs/test/options/viewMode.js
@@ -0,0 +1,100 @@
+QUnit.test('options#viewMode: 0', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(4);
+
+ return new Cropper(image, {
+ // viewMode: 0,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var canvasData = {
+ left: 100,
+ top: 100,
+ width: 160,
+ height: 90
+ };
+ var changedCanvasData = cropper.setCanvasData(canvasData).getCanvasData();
+
+ assert.strictEqual(changedCanvasData.left, canvasData.left);
+ assert.strictEqual(changedCanvasData.top, canvasData.top);
+ assert.strictEqual(changedCanvasData.width, canvasData.width);
+ assert.strictEqual(changedCanvasData.height, canvasData.height);
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#viewMode: 1', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ viewMode: 1,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var canvasData = cropper.zoom(-0.5).getCanvasData(); // Zoom out
+ var cropBoxData = cropper.getCropBoxData();
+
+ assert.ok(canvasData.width >= cropBoxData.width);
+ assert.ok(canvasData.height >= cropBoxData.height);
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#viewMode: 2', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ viewMode: 2,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var canvasData = cropper.zoom(-0.5).getCanvasData(); // Zoom out
+ var containerData = cropper.getContainerData();
+
+ assert.ok(canvasData.width >= containerData.width ||
+ canvasData.height >= containerData.height);
+
+ done();
+ }
+ });
+});
+
+QUnit.test('options#viewMode: 3', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(4);
+
+ return new Cropper(image, {
+ viewMode: 3,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var canvasData = cropper.zoom(-0.5).getCanvasData(); // Zoom out
+ var containerData = cropper.getContainerData();
+
+ assert.ok(canvasData.left <= 0);
+ assert.ok(canvasData.top <= 0);
+ assert.ok(canvasData.width >= containerData.width);
+ assert.ok(canvasData.height >= containerData.height);
+
+ done();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/zoom.js b/library/cropperjs/test/options/zoom.js
new file mode 100644
index 000000000..51ebc76ad
--- /dev/null
+++ b/library/cropperjs/test/options/zoom.js
@@ -0,0 +1,46 @@
+QUnit.test('options#zoom', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(3);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+
+ cropper.zoom(0.1);
+
+ done();
+ },
+
+ zoom: function (e) {
+ assert.ok(e.detail.ratio > 0);
+ assert.ok(e.detail.oldRatio > 0);
+ assert.ok(e.detail.ratio > e.detail.oldRatio);
+ }
+ });
+});
+
+QUnit.test('options#zoom: default prevented', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ ready: function () {
+ var cropper = this.cropper;
+ var canvasData = cropper.getCanvasData();
+
+ assert.deepEqual(cropper.zoom(0.1).getCanvasData(), canvasData);
+
+ done();
+ },
+
+ zoom: function (e) {
+ e.preventDefault();
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/zoomOnWheel.js b/library/cropperjs/test/options/zoomOnWheel.js
new file mode 100644
index 000000000..1a1bf6dce
--- /dev/null
+++ b/library/cropperjs/test/options/zoomOnWheel.js
@@ -0,0 +1,47 @@
+QUnit.test('options#zoomOnWheel: true', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(1);
+
+ return new Cropper(image, {
+ // zoomOnWheel: true,
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ util.dispatchEvent(cropper.cropper, 'wheel');
+
+ done();
+ },
+
+ zoom: function () {
+ assert.ok(true);
+ }
+ });
+});
+
+QUnit.test('options#zoomOnWheel: false', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(0);
+
+ return new Cropper(image, {
+ zoomOnWheel: false,
+
+ ready: function () {
+ var cropper = this.cropper;
+
+ util.dispatchEvent(cropper.cropper, 'wheel');
+
+ done();
+ },
+
+ zoom: function () {
+ assert.ok(false);
+ }
+ });
+});
diff --git a/library/cropperjs/test/options/zoomable.js b/library/cropperjs/test/options/zoomable.js
new file mode 100644
index 000000000..9f8ec6fce
--- /dev/null
+++ b/library/cropperjs/test/options/zoomable.js
@@ -0,0 +1,51 @@
+QUnit.test('options#zoomable: true', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(3);
+
+ return new Cropper(image, {
+ // zoomable: true,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var canvasData = cropper.getCanvasData();
+ var changedCanvasData = cropper.zoom(0.1).getCanvasData();
+
+ assert.ok(changedCanvasData.width > canvasData.width);
+ assert.ok(changedCanvasData.height > canvasData.height);
+
+ done();
+ },
+ zoom: function () {
+ assert.ok(true);
+ }
+ });
+});
+
+QUnit.test('options#zoomable: false', function (assert) {
+ var done = assert.async();
+ var util = window.Util;
+ var image = util.createImage();
+
+ assert.expect(2);
+
+ return new Cropper(image, {
+ zoomable: false,
+
+ ready: function () {
+ var cropper = this.cropper;
+ var canvasData = cropper.getCanvasData();
+ var changedCanvasData = cropper.zoom(0.1).getCanvasData();
+
+ assert.ok(changedCanvasData.width === canvasData.width);
+ assert.ok(changedCanvasData.height === canvasData.height);
+
+ done();
+ },
+ zoom: function () {
+ assert.ok(false);
+ }
+ });
+});