tui-image-editor.upgrade
Version:
TOAST UI Component: ImageEditor(fix bug)
43,955 lines • 1.65 MB
JavaScript
/*!
* tui-image-editor.upgrade.js
* @version 3.2.3-rc.35
* @author lizhekang <lizhekang@hotmail.com>
* @license MIT
*/
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("tui-code-snippet"));
else if(typeof define === 'function' && define.amd)
define(["tui-code-snippet"], factory);
else if(typeof exports === 'object')
exports["ImageEditor"] = factory(require("tui-code-snippet"));
else
root["tui"] = root["tui"] || {}, root["tui"]["ImageEditor"] = factory((root["tui"] && root["tui"]["util"]));
})(this, function(__WEBPACK_EXTERNAL_MODULE_3__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "dist";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
__webpack_require__(1);
var _imageEditor = __webpack_require__(2);
var _imageEditor2 = _interopRequireDefault(_imageEditor);
__webpack_require__(175);
__webpack_require__(177);
__webpack_require__(178);
__webpack_require__(179);
__webpack_require__(180);
__webpack_require__(181);
__webpack_require__(182);
__webpack_require__(183);
__webpack_require__(184);
__webpack_require__(185);
__webpack_require__(186);
__webpack_require__(187);
__webpack_require__(188);
__webpack_require__(189);
__webpack_require__(190);
__webpack_require__(191);
__webpack_require__(192);
__webpack_require__(193);
__webpack_require__(194);
__webpack_require__(195);
__webpack_require__(196);
__webpack_require__(197);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
module.exports = _imageEditor2.default;
// commands
/***/ }),
/* 1 */
/***/ (function(module, exports) {
"use strict";
// https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
// Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/if (!Element.prototype.matches)
Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
if (!Element.prototype.closest) Element.prototype.closest = function (s) {
var el = this;
if (!document.documentElement.contains(el)) return null;
do {
if (el.matches(s)) return el;
el = el.parentElement || el.parentNode;
} while (el !== null && el.nodeType === 1);
return null;
};
/*
* classList.js: Cross-browser full element.classList implementation.
* 1.1.20170427
*
* By Eli Grey, http://eligrey.com
* License: Dedicated to the public domain.
* See https://github.com/eligrey/classList.js/blob/master/LICENSE.md
*/
/*global self, document, DOMException */
/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js */
if ("document" in window.self) {
// Full polyfill for browsers with no classList support
// Including IE < Edge missing SVGElement.classList
if (!("classList" in document.createElement("_")) || document.createElementNS && !("classList" in document.createElementNS("http://www.w3.org/2000/svg", "g"))) {
(function (view) {
"use strict";
if (!('Element' in view)) return;
var classListProp = "classList",
protoProp = "prototype",
elemCtrProto = view.Element[protoProp],
objCtr = Object,
strTrim = String[protoProp].trim || function () {
return this.replace(/^\s+|\s+$/g, "");
},
arrIndexOf = Array[protoProp].indexOf || function (item) {
var i = 0,
len = this.length;
for (; i < len; i++) {
if (i in this && this[i] === item) {
return i;
}
}
return -1;
}
// Vendors: please allow content code to instantiate DOMExceptions
,
DOMEx = function DOMEx(type, message) {
this.name = type;
this.code = DOMException[type];
this.message = message;
},
checkTokenAndGetIndex = function checkTokenAndGetIndex(classList, token) {
if (token === "") {
throw new DOMEx("SYNTAX_ERR", "An invalid or illegal string was specified");
}
if (/\s/.test(token)) {
throw new DOMEx("INVALID_CHARACTER_ERR", "String contains an invalid character");
}
return arrIndexOf.call(classList, token);
},
ClassList = function ClassList(elem) {
var trimmedClasses = strTrim.call(elem.getAttribute("class") || ""),
classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [],
i = 0,
len = classes.length;
for (; i < len; i++) {
this.push(classes[i]);
}
this._updateClassName = function () {
elem.setAttribute("class", this.toString());
};
},
classListProto = ClassList[protoProp] = [],
classListGetter = function classListGetter() {
return new ClassList(this);
};
// Most DOMException implementations don't allow calling DOMException's toString()
// on non-DOMExceptions. Error's toString() is sufficient here.
DOMEx[protoProp] = Error[protoProp];
classListProto.item = function (i) {
return this[i] || null;
};
classListProto.contains = function (token) {
token += "";
return checkTokenAndGetIndex(this, token) !== -1;
};
classListProto.add = function () {
var tokens = arguments,
i = 0,
l = tokens.length,
token,
updated = false;
do {
token = tokens[i] + "";
if (checkTokenAndGetIndex(this, token) === -1) {
this.push(token);
updated = true;
}
} while (++i < l);
if (updated) {
this._updateClassName();
}
};
classListProto.remove = function () {
var tokens = arguments,
i = 0,
l = tokens.length,
token,
updated = false,
index;
do {
token = tokens[i] + "";
index = checkTokenAndGetIndex(this, token);
while (index !== -1) {
this.splice(index, 1);
updated = true;
index = checkTokenAndGetIndex(this, token);
}
} while (++i < l);
if (updated) {
this._updateClassName();
}
};
classListProto.toggle = function (token, force) {
token += "";
var result = this.contains(token),
method = result ? force !== true && "remove" : force !== false && "add";
if (method) {
this[method](token);
}
if (force === true || force === false) {
return force;
} else {
return !result;
}
};
classListProto.toString = function () {
return this.join(" ");
};
if (objCtr.defineProperty) {
var classListPropDesc = {
get: classListGetter,
enumerable: true,
configurable: true
};
try {
objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
} catch (ex) {
// IE 8 doesn't support enumerable:true
// adding undefined to fight this issue https://github.com/eligrey/classList.js/issues/36
// modernie IE8-MSW7 machine has IE8 8.0.6001.18702 and is affected
if (ex.number === undefined || ex.number === -0x7FF5EC54) {
classListPropDesc.enumerable = false;
objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
}
}
} else if (objCtr[protoProp].__defineGetter__) {
elemCtrProto.__defineGetter__(classListProp, classListGetter);
}
})(window.self);
}
// There is full or partial native classList support, so just check if we need
// to normalize the add/remove and toggle APIs.
(function () {
"use strict";
var testElement = document.createElement("_");
testElement.classList.add("c1", "c2");
// Polyfill for IE 10/11 and Firefox <26, where classList.add and
// classList.remove exist but support only one argument at a time.
if (!testElement.classList.contains("c2")) {
var createMethod = function createMethod(method) {
var original = DOMTokenList.prototype[method];
DOMTokenList.prototype[method] = function (token) {
var i,
len = arguments.length;
for (i = 0; i < len; i++) {
token = arguments[i];
original.call(this, token);
}
};
};
createMethod('add');
createMethod('remove');
}
testElement.classList.toggle("c3", false);
// Polyfill for IE 10 and Firefox <24, where classList.toggle does not
// support the second argument.
if (testElement.classList.contains("c3")) {
var _toggle = DOMTokenList.prototype.toggle;
DOMTokenList.prototype.toggle = function (token, force) {
if (1 in arguments && !this.contains(token) === !force) {
return force;
} else {
return _toggle.call(this, token);
}
};
}
testElement = null;
})();
}
/*!
* @copyright Copyright (c) 2017 IcoMoon.io
* @license Licensed under MIT license
* See https://github.com/Keyamoon/svgxuse
* @version 1.2.6
*/
/*jslint browser: true */
/*global XDomainRequest, MutationObserver, window */
(function () {
"use strict";
if (typeof window !== "undefined" && window.addEventListener) {
var cache = Object.create(null); // holds xhr objects to prevent multiple requests
var checkUseElems;
var tid; // timeout id
var debouncedCheck = function debouncedCheck() {
clearTimeout(tid);
tid = setTimeout(checkUseElems, 100);
};
var unobserveChanges = function unobserveChanges() {
return;
};
var observeChanges = function observeChanges() {
var observer;
window.addEventListener("resize", debouncedCheck, false);
window.addEventListener("orientationchange", debouncedCheck, false);
if (window.MutationObserver) {
observer = new MutationObserver(debouncedCheck);
observer.observe(document.documentElement, {
childList: true,
subtree: true,
attributes: true
});
unobserveChanges = function unobserveChanges() {
try {
observer.disconnect();
window.removeEventListener("resize", debouncedCheck, false);
window.removeEventListener("orientationchange", debouncedCheck, false);
} catch (ignore) {}
};
} else {
document.documentElement.addEventListener("DOMSubtreeModified", debouncedCheck, false);
unobserveChanges = function unobserveChanges() {
document.documentElement.removeEventListener("DOMSubtreeModified", debouncedCheck, false);
window.removeEventListener("resize", debouncedCheck, false);
window.removeEventListener("orientationchange", debouncedCheck, false);
};
}
};
var createRequest = function createRequest(url) {
// In IE 9, cross origin requests can only be sent using XDomainRequest.
// XDomainRequest would fail if CORS headers are not set.
// Therefore, XDomainRequest should only be used with cross origin requests.
function getOrigin(loc) {
var a;
if (loc.protocol !== undefined) {
a = loc;
} else {
a = document.createElement("a");
a.href = loc;
}
return a.protocol.replace(/:/g, "") + a.host;
}
var Request;
var origin;
var origin2;
if (window.XMLHttpRequest) {
Request = new XMLHttpRequest();
origin = getOrigin(location);
origin2 = getOrigin(url);
if (Request.withCredentials === undefined && origin2 !== "" && origin2 !== origin) {
Request = XDomainRequest || undefined;
} else {
Request = XMLHttpRequest;
}
}
return Request;
};
var xlinkNS = "http://www.w3.org/1999/xlink";
checkUseElems = function checkUseElems() {
var base;
var bcr;
var fallback = ""; // optional fallback URL in case no base path to SVG file was given and no symbol definition was found.
var hash;
var href;
var i;
var inProgressCount = 0;
var isHidden;
var Request;
var url;
var uses;
var xhr;
function observeIfDone() {
// If done with making changes, start watching for chagnes in DOM again
inProgressCount -= 1;
if (inProgressCount === 0) {
// if all xhrs were resolved
unobserveChanges(); // make sure to remove old handlers
observeChanges(); // watch for changes to DOM
}
}
function attrUpdateFunc(spec) {
return function () {
if (cache[spec.base] !== true) {
spec.useEl.setAttributeNS(xlinkNS, "xlink:href", "#" + spec.hash);
if (spec.useEl.hasAttribute("href")) {
spec.useEl.setAttribute("href", "#" + spec.hash);
}
}
};
}
function onloadFunc(xhr) {
return function () {
var body = document.body;
var x = document.createElement("x");
var svg;
xhr.onload = null;
x.innerHTML = xhr.responseText;
svg = x.getElementsByTagName("svg")[0];
if (svg) {
svg.setAttribute("aria-hidden", "true");
svg.style.position = "absolute";
svg.style.width = 0;
svg.style.height = 0;
svg.style.overflow = "hidden";
body.insertBefore(svg, body.firstChild);
}
observeIfDone();
};
}
function onErrorTimeout(xhr) {
return function () {
xhr.onerror = null;
xhr.ontimeout = null;
observeIfDone();
};
}
unobserveChanges(); // stop watching for changes to DOM
// find all use elements
uses = document.getElementsByTagName("use");
for (i = 0; i < uses.length; i += 1) {
try {
bcr = uses[i].getBoundingClientRect();
} catch (ignore) {
// failed to get bounding rectangle of the use element
bcr = false;
}
href = uses[i].getAttribute("href") || uses[i].getAttributeNS(xlinkNS, "href") || uses[i].getAttribute("xlink:href");
if (href && href.split) {
url = href.split("#");
} else {
url = ["", ""];
}
base = url[0];
hash = url[1];
isHidden = bcr && bcr.left === 0 && bcr.right === 0 && bcr.top === 0 && bcr.bottom === 0;
if (bcr && bcr.width === 0 && bcr.height === 0 && !isHidden) {
// the use element is empty
// if there is a reference to an external SVG, try to fetch it
// use the optional fallback URL if there is no reference to an external SVG
if (fallback && !base.length && hash && !document.getElementById(hash)) {
base = fallback;
}
if (uses[i].hasAttribute("href")) {
uses[i].setAttributeNS(xlinkNS, "xlink:href", href);
}
if (base.length) {
// schedule updating xlink:href
xhr = cache[base];
if (xhr !== true) {
// true signifies that prepending the SVG was not required
setTimeout(attrUpdateFunc({
useEl: uses[i],
base: base,
hash: hash
}), 0);
}
if (xhr === undefined) {
Request = createRequest(base);
if (Request !== undefined) {
xhr = new Request();
cache[base] = xhr;
xhr.onload = onloadFunc(xhr);
xhr.onerror = onErrorTimeout(xhr);
xhr.ontimeout = onErrorTimeout(xhr);
xhr.open("GET", base);
xhr.send();
inProgressCount += 1;
}
}
}
} else {
if (!isHidden) {
if (cache[base] === undefined) {
// remember this URL if the use element was not empty and no request was sent
cache[base] = true;
} else if (cache[base].onload) {
// if it turns out that prepending the SVG is not necessary,
// abort the in-progress xhr.
cache[base].abort();
delete cache[base].onload;
cache[base] = true;
}
} else if (base.length && cache[base]) {
setTimeout(attrUpdateFunc({
useEl: uses[i],
base: base,
hash: hash
}), 0);
}
}
}
uses = "";
inProgressCount += 1;
observeIfDone();
};
var _winLoad;
_winLoad = function winLoad() {
window.removeEventListener("load", _winLoad, false); // to prevent memory leaks
tid = setTimeout(checkUseElems, 0);
};
if (document.readyState !== "complete") {
// The load event fires when all resources have finished loading, which allows detecting whether SVG use elements are empty.
window.addEventListener("load", _winLoad, false);
} else {
// No need to add a listener if the document is already loaded, initialize immediately.
_winLoad();
}
}
})();
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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; }; }(); /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Image-editor application class
*/
var _tuiCodeSnippet = __webpack_require__(3);
var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _invoker2 = __webpack_require__(68);
var _invoker3 = _interopRequireDefault(_invoker2);
var _ui = __webpack_require__(74);
var _ui2 = _interopRequireDefault(_ui);
var _action = __webpack_require__(102);
var _action2 = _interopRequireDefault(_action);
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _graphics = __webpack_require__(104);
var _graphics2 = _interopRequireDefault(_graphics);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
var _util = __webpack_require__(72);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var events = _consts2.default.eventNames;
var commands = _consts2.default.commandNames;
var keyCodes = _consts2.default.keyCodes,
rejectMessages = _consts2.default.rejectMessages;
var isUndefined = _tuiCodeSnippet2.default.isUndefined,
forEach = _tuiCodeSnippet2.default.forEach,
CustomEvents = _tuiCodeSnippet2.default.CustomEvents;
/**
* Image editor
* @class
* @param {string|jQuery|HTMLElement} wrapper - Wrapper's element or selector
* @param {Object} [options] - Canvas max width & height of css
* @param {number} [options.includeUI] - Use the provided UI
* @param {Object} [options.includeUI.loadImage] - Basic editing image
* @param {string} options.includeUI.loadImage.path - image path
* @param {string} options.includeUI.loadImage.name - image name
* @param {Object} [options.includeUI.theme] - Theme object
* @param {Array} [options.includeUI.menu] - It can be selected when only specific menu is used. [default all]
* @param {string} [options.includeUI.initMenu] - The first menu to be selected and started.
* @param {string} [options.includeUI.menuBarPosition=bottom] - Menu bar position [top | bottom | left | right]
* @param {number} options.cssMaxWidth - Canvas css-max-width
* @param {number} options.cssMaxHeight - Canvas css-max-height
* @param {Boolean} [options.usageStatistics=true] - Let us know the hostname. If you don't want to send the hostname, please set to false.
* @example
* var ImageEditor = require('tui-image-editor');
* var blackTheme = require('./js/theme/black-theme.js');
* var instance = new ImageEditor(document.querySelector('#tui-image-editor'), {
* includeUI: {
* loadImage: {
* path: 'img/sampleImage.jpg',
* name: 'SampleImage'
* },
* theme: blackTheme, // or whiteTheme
* menu: ['shape', 'filter'],
* initMenu: 'filter',
* menuBarPosition: 'bottom'
* },
* cssMaxWidth: 700,
* cssMaxHeight: 500,
* selectionStyle: {
* cornerSize: 20,
* rotatingPointOffset: 70
* }
* });
*/
var ImageEditor = function () {
function ImageEditor(wrapper, options) {
_classCallCheck(this, ImageEditor);
options = _tuiCodeSnippet2.default.extend({
includeUI: false,
usageStatistics: true
}, options);
this.mode = null;
this.activeObjectId = null;
this.preventBackspaceDel = typeof options.preventBackspaceDel === 'undefined' ? false : options.preventBackspaceDel;
/**
* UI instance
* @type {Ui}
*/
if (options.includeUI) {
this.ui = new _ui2.default(wrapper, options.includeUI, this.getActions());
options = this.ui.setUiDefaultSelectionStyle(options);
}
/**
* Invoker
* @type {Invoker}
* @private
*/
this._invoker = new _invoker3.default();
/**
* Graphics instance
* @type {Graphics}
* @private
*/
this._graphics = new _graphics2.default(this.ui ? this.ui.getEditorArea() : wrapper, {
cssMaxWidth: options.cssMaxWidth,
cssMaxHeight: options.cssMaxHeight,
useItext: !!this.ui,
useDragAddIcon: !!this.ui,
noSelector: options.noSelector || false
});
/**
* Event handler list
* @type {Object}
* @private
*/
this._handlers = {
keydown: this._onKeyDown.bind(this),
mousedown: this._onMouseDown.bind(this),
objectActivated: this._onObjectActivated.bind(this),
objectMoved: this._onObjectMoved.bind(this),
objectScaled: this._onObjectScaled.bind(this),
// createdPath: this._onCreatedPath,
addText: this._onAddText.bind(this),
addObject: this._onAddObject.bind(this),
addObjectAfter: this._onAddObjectAfter.bind(this),
textEditing: this._onTextEditing.bind(this),
textChanged: this._onTextChanged.bind(this),
iconCreateResize: this._onIconCreateResize.bind(this),
iconCreateEnd: this._onIconCreateEnd.bind(this),
selectionCleared: this._selectionCleared.bind(this),
selectionCreated: this._selectionCreated.bind(this),
objectRotateFix: this._onObjectRotateFix.bind(this),
objectRemove: this._onObjectRemove.bind(this)
};
this._attachInvokerEvents();
this._attachGraphicsEvents();
this._attachDomEvents();
this._setSelectionStyle(options.selectionStyle, {
applyCropSelectionStyle: options.applyCropSelectionStyle,
applyGroupSelectionStyle: options.applyGroupSelectionStyle
});
if (options.usageStatistics) {
(0, _util.sendHostName)();
}
if (this.ui) {
this.ui.initCanvas();
this.setReAction();
}
}
/**
* Image filter result
* @typedef {Object} FilterResult
* @property {string} type - filter type like 'mask', 'Grayscale' and so on
* @property {string} action - action type like 'add', 'remove'
*/
/**
* Flip status
* @typedef {Object} FlipStatus
* @property {boolean} flipX - x axis
* @property {boolean} flipY - y axis
* @property {Number} angle - angle
*/
/**
* Rotation status
* @typedef {Number} RotateStatus
* @property {Number} angle - angle
*/
/**
* Old and new Size
* @typedef {Object} SizeChange
* @property {Number} oldWidth - old width
* @property {Number} oldHeight - old height
* @property {Number} newWidth - new width
* @property {Number} newHeight - new height
*/
/**
* @typedef {string} ErrorMsg - {string} error message
*/
/**
* @typedef {Object} ObjectProps - graphics object properties
* @property {number} id - object id
* @property {string} type - object type
* @property {string} text - text content
* @property {string} left - Left
* @property {string} top - Top
* @property {string} width - Width
* @property {string} height - Height
* @property {string} fill - Color
* @property {string} stroke - Stroke
* @property {string} strokeWidth - StrokeWidth
* @property {string} fontFamily - Font type for text
* @property {number} fontSize - Font Size
* @property {string} fontStyle - Type of inclination (normal / italic)
* @property {string} fontWeight - Type of thicker or thinner looking (normal / bold)
* @property {string} textAlign - Type of text align (left / center / right)
* @property {string} textDecoraiton - Type of line (underline / line-throgh / overline)
*/
/**
* Set selection style by init option
* @param {Object} selectionStyle - Selection styles
* @param {Object} applyTargets - Selection apply targets
* @param {boolean} applyCropSelectionStyle - whether apply with crop selection style or not
* @param {boolean} applyGroupSelectionStyle - whether apply with group selection style or not
* @private
*/
_createClass(ImageEditor, [{
key: '_setSelectionStyle',
value: function _setSelectionStyle(selectionStyle, _ref) {
var applyCropSelectionStyle = _ref.applyCropSelectionStyle,
applyGroupSelectionStyle = _ref.applyGroupSelectionStyle;
if (selectionStyle) {
this._graphics.setSelectionStyle(selectionStyle);
}
if (applyCropSelectionStyle) {
this._graphics.setCropSelectionStyle(selectionStyle);
}
if (applyGroupSelectionStyle) {
this.on('selectionCreated', function (eventTarget) {
if (eventTarget.type === 'group') {
eventTarget.set(selectionStyle);
}
});
}
}
/**
* Attach invoker events
* @private
*/
}, {
key: '_attachInvokerEvents',
value: function _attachInvokerEvents() {
var UNDO_STACK_CHANGED = events.UNDO_STACK_CHANGED,
REDO_STACK_CHANGED = events.REDO_STACK_CHANGED;
/**
* Undo stack changed event
* @event ImageEditor#undoStackChanged
* @param {Number} length - undo stack length
* @example
* imageEditor.on('undoStackChanged', function(length) {
* console.log(length);
* });
*/
this._invoker.on(UNDO_STACK_CHANGED, this.fire.bind(this, UNDO_STACK_CHANGED));
/**
* Redo stack changed event
* @event ImageEditor#redoStackChanged
* @param {Number} length - redo stack length
* @example
* imageEditor.on('redoStackChanged', function(length) {
* console.log(length);
* });
*/
this._invoker.on(REDO_STACK_CHANGED, this.fire.bind(this, REDO_STACK_CHANGED));
}
/**
* Attach canvas events
* @private
*/
}, {
key: '_attachGraphicsEvents',
value: function _attachGraphicsEvents() {
this._graphics.on({
'mousedown': this._handlers.mousedown,
'objectMoved': this._handlers.objectMoved,
'objectScaled': this._handlers.objectScaled,
'objectActivated': this._handlers.objectActivated,
'addText': this._handlers.addText,
'addObject': this._handlers.addObject,
'textEditing': this._handlers.textEditing,
'textChanged': this._handlers.textChanged,
'iconCreateResize': this._handlers.iconCreateResize,
'iconCreateEnd': this._handlers.iconCreateEnd,
'selectionCleared': this._handlers.selectionCleared,
'selectionCreated': this._handlers.selectionCreated,
'addObjectAfter': this._handlers.addObjectAfter,
'objectRotateFix': this._handlers.objectRotateFix,
'objectRemove': this._handlers.objectRemove
});
}
/**
* Attach dom events
* @private
*/
}, {
key: '_attachDomEvents',
value: function _attachDomEvents() {
// ImageEditor supports IE 9 higher
document.addEventListener('keydown', this._handlers.keydown);
}
/**
* Detach dom events
* @private
*/
}, {
key: '_detachDomEvents',
value: function _detachDomEvents() {
// ImageEditor supports IE 9 higher
document.removeEventListener('keydown', this._handlers.keydown);
}
/**
* Keydown event handler
* @param {KeyboardEvent} e - Event object
* @private
*/
/* eslint-disable complexity */
}, {
key: '_onKeyDown',
value: function _onKeyDown(e) {
var activeObject = this._graphics.getActiveObject();
var activeObjectGroup = this._graphics.getActiveGroupObject();
var existRemoveObject = activeObject || activeObjectGroup;
if ((e.ctrlKey || e.metaKey) && e.keyCode === keyCodes.Z) {
// There is no error message on shortcut when it's empty
this.undo()['catch'](function () {});
}
if ((e.ctrlKey || e.metaKey) && e.keyCode === keyCodes.Y) {
// There is no error message on shortcut when it's empty
this.redo()['catch'](function () {});
}
if (!this.preventBackspaceDel && (e.keyCode === keyCodes.BACKSPACE || e.keyCode === keyCodes.DEL) && existRemoveObject) {
e.preventDefault();
this.removeActiveObject();
}
}
/* eslint-enable complexity */
/**
* Remove Active Object
*/
}, {
key: 'removeActiveObject',
value: function removeActiveObject() {
var activeObject = this._graphics.getActiveObject();
var activeObjectGroup = this._graphics.getActiveGroupObject();
if (activeObjectGroup) {
var objects = activeObjectGroup.getObjects();
this.discardSelection();
this._removeObjectStream(objects);
} else if (activeObject) {
var activeObjectId = this._graphics.getObjectId(activeObject);
this.removeObject(activeObjectId);
}
}
/**
* RemoveObject Sequential processing for prevent invoke lock
* @param {Array.<Object>} targetObjects - target Objects for remove
* @returns {object} targetObjects
* @private
*/
}, {
key: '_removeObjectStream',
value: function _removeObjectStream(targetObjects) {
var _this = this;
if (!targetObjects.length) {
return true;
}
var targetObject = targetObjects.pop();
return this.removeObject(this._graphics.getObjectId(targetObject)).then(function () {
return _this._removeObjectStream(targetObjects);
});
}
/**
* mouse down event handler
* @param {Event} event mouse down event
* @param {Object} originPointer origin pointer
* @param {Number} originPointer.x x position
* @param {Number} originPointer.y y position
* @private
*/
}, {
key: '_onMouseDown',
value: function _onMouseDown(event, originPointer) {
/**
* The mouse down event with position x, y on canvas
* @event ImageEditor#mousedown
* @param {Object} event - browser mouse event object
* @param {Object} originPointer origin pointer
* @param {Number} originPointer.x x position
* @param {Number} originPointer.y y position
* @example
* imageEditor.on('mousedown', function(event, originPointer) {
* console.log(event);
* console.log(originPointer);
* if (imageEditor.hasFilter('colorFilter')) {
* imageEditor.applyFilter('colorFilter', {
* x: parseInt(originPointer.x, 10),
* y: parseInt(originPointer.y, 10)
* });
* }
* });
*/
this.fire(events.MOUSE_DOWN, event, originPointer);
}
/**
* Add a 'addObject' command
* @param {Object} obj - Fabric object
* @private
*/
}, {
key: '_pushAddObjectCommand',
value: function _pushAddObjectCommand(obj) {
var command = _command2.default.create(commands.ADD_OBJECT, this._graphics, obj);
this._invoker.pushUndoStack(command);
}
/**
* 'objectActivated' event handler
* @param {ObjectProps} props - object properties
* @private
*/
}, {
key: '_onObjectActivated',
value: function _onObjectActivated(props) {
/**
* The event when object is selected(aka activated).
* @event ImageEditor#objectActivated
* @param {ObjectProps} objectProps - object properties
* @example
* imageEditor.on('objectActivated', function(props) {
* console.log(props);
* console.log(props.type);
* console.log(props.id);
* });
*/
this.fire(events.OBJECT_ACTIVATED, props);
}
/**
* 'objectMoved' event handler
* @param {ObjectProps} props - object properties
* @private
*/
}, {
key: '_onObjectMoved',
value: function _onObjectMoved(props) {
/**
* The event when object is moved
* @event ImageEditor#objectMoved
* @param {ObjectProps} props - object properties
* @example
* imageEditor.on('objectMoved', function(props) {
* console.log(props);
* console.log(props.type);
* });
*/
this.fire(events.OBJECT_MOVED, props);
}
}, {
key: '_onObjectRotateFix',
value: function _onObjectRotateFix(data) {
/**
* The event when object is moved
* @event ImageEditor#objectMoved
* @param {ObjectProps} props - object properties
* @example
* imageEditor.on('objectRotateFix', function(data) {
* console.log(data);
* });
*/
this.fire(events.OBJECT_ROTATE_FIX, data);
}
}, {
key: '_onObjectRemove',
value: function _onObjectRemove(data) {
/**
* The event when object is moved
* @event ImageEditor#objectMoved
* @param {ObjectProps} props - object properties
* @example
* imageEditor.on('objectRemove', function(data) {
* console.log(data);
* });
*/
this.fire(events.OBJECT_REMOVE, data);
}
/**
* 'objectScaled' event handler
* @param {ObjectProps} props - object properties
* @private
*/
}, {
key: '_onObjectScaled',
value: function _onObjectScaled(props) {
/**
* The event when scale factor is changed
* @event ImageEditor#objectScaled
* @param {ObjectProps} props - object properties
* @example
* imageEditor.on('objectScaled', function(props) {
* console.log(props);
* console.log(props.type);
* });
*/
this.fire(events.OBJECT_SCALED, props);
}
/**
* Get current drawing mode
* @returns {string}
* @example
* // Image editor drawing mode
* //
* // NORMAL: 'NORMAL'
* // CROPPER: 'CROPPER'
* // FREE_DRAWING: 'FREE_DRAWING'
* // LINE_DRAWING: 'LINE_DRAWING'
* // TEXT: 'TEXT'
* //
* if (imageEditor.getDrawingMode() === 'FREE_DRAWING') {
* imageEditor.stopDrawingMode();
* }
*/
}, {
key: 'getDrawingMode',
value: function getDrawingMode() {
return this._graphics.getDrawingMode();
}
/**
* Clear all objects
* @returns {Promise}
* @example
* imageEditor.clearObjects();
*/
}, {
key: 'clearObjects',
value: function clearObjects() {
return this.execute(commands.CLEAR_OBJECTS);
}
/**
* Deactivate all objects
* @example
* imageEditor.deactivateAll();
*/
}, {
key: 'deactivateAll',
value: function deactivateAll() {
this._graphics.deactivateAll();
this._graphics.renderAll();
}
/**
* discard selction
* @example
* imageEditor.discardSelection();
*/
}, {
key: 'discardSelection',
value: function discardSelection() {
this._graphics.discardSelection();
}
/**
* selectable status change
* @param {boolean} selectable - selctable status
* @example
* imageEditor.changeSelectableAll(false); // or true
*/
}, {
key: 'changeSelectableAll',
value: function changeSelectableAll(selectable) {
this._graphics.changeSelectableAll(selectable);
}
/**
* Invoke command
* @param {String} commandName - Command name
* @param {...*} args - Arguments for creating command
* @returns {Promise}
* @private
*/
}, {
key: 'execute',
value: function execute(commandName) {
var _invoker;
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
// Inject an Graphics instance as first parameter
var theArgs = [this._graphics].concat(args);
return (_invoker = this._invoker).execute.apply(_invoker, [commandName].concat(theArgs));
}
/**
* Undo
* @returns {Promise}
* @example
* imageEditor.undo();
*/
}, {
key: 'undo',
value: function undo() {
return this._invoker.undo();
}
/**
* Redo
* @returns {Promise}
* @example
* imageEditor.redo();
*/
}, {
key: 'redo',
value: function redo() {
return this._invoker.redo();
}
/**
* Load image from file
* @param {File} imgFile - Image file
* @param {string} [imageName] - imageName
* @returns {Promise<SizeChange, ErrorMsg>}
* @example
* imageEditor.loadImageFromFile(file).then(result => {
* console.log('old : ' + result.oldWidth + ', ' + result.oldHeight);
* console.log('new : ' + result.newWidth + ', ' + result.newHeight);
* });
*/
}, {
key: 'loadImageFromFile',
value: function loadImageFromFile(imgFile, imageName) {
if (!imgFile) {
return _promise2.default.reject(rejectMessages.invalidParameters);
}
var imgUrl = URL.createObjectURL(imgFile);
imageName = imageName || imgFile.name;
return this.loadImageFromURL(imgUrl, imageName).then(function (value) {
URL.revokeObjectURL(imgFile);
return value;
});
}
/**
* Load image from url
* @param {string} url - File url
* @param {string} imageName - imageName
* @returns {Promise<SizeChange, ErrorMsg>}
* @example
* imageEditor.loadImageFromURL('http://url/testImage.png', 'lena').then(result => {
* console.log('old : ' + result.oldWidth + ', ' + result.oldHeight);
* console.log('new : ' + result.newWidth + ', ' + result.newHeight);
* });
*/
}, {
key: 'loadImageFromURL',
value: function loadImageFromURL(url, imageName) {
if (!imageName || !url) {
return _promise2.default.reject(rejectMessages.invalidParameters);
}
return this.execute(commands.LOAD_IMAGE, imageName, url);
}
/**
* Add image object on canvas
* @param {string} imgUrl - Image url to make object
* @returns {Promise<ObjectProps, ErrorMsg>}
* @example
* imageEditor.addImageObject('path/fileName.jpg').then(objectProps => {
* console.log(ojectProps.id);
* });
*/
}, {
key: 'addImageObject',
value: function addImageObject(imgUrl) {
if (!imgUrl) {
return _promise2.default.reject(rejectMessages.invalidParameters);
}
return this.execute(commands.ADD_IMAGE_OBJECT, imgUrl);
}
/**
* Start a drawing mode. If the current mode is not 'NORMAL', 'stopDrawingMode()' will be called first.
* @param {String} mode Can be one of <I>'CROPPER', 'FREE_DRAWING', 'LINE_DRAWING', 'TEXT', 'SHAPE'</I>
* @param {Object} [option] parameters of drawing mode, it's available with 'FREE_DRAWING', 'LINE_DRAWING'
* @param {Number} [option.width] brush width
* @param {String} [option.color] brush color
* @returns {boolean} true if success or false
* @example
* imageEditor.startDrawingMode('FREE_DRAWING', {
* width: 10,
* color: 'rgba(255,0,0,0.5)'
* });
*/
}, {
key: 'startDrawingMode',
value: function startDrawingMode(mode, option) {
return this._graphics.startDrawingMode(mode, option);
}
/**
* Stop the current drawing mode and back to the 'NORMAL' mode
* @example
* imageEditor.stopDrawingMode();
*/
}, {
key: 'stopDrawingMode',
value: function stopDrawingMode() {
this._graphics.stopDrawingMode();
}
/**
* Crop this image with rect
* @param {Object} rect crop rect
* @param {Number} rect.left left position
* @param {Number} rect.top top position
* @param {Number} rect.width width
* @param {Number} rect.height height
* @returns {Promise}
* @example
* imageEditor.crop(imageEditor.getCropzoneRect());
*/
}, {
key: 'crop',
value: function crop(rect) {
var data = this._graphics.getCroppedImageData(rect);
if (!data) {
return _promise2.default.reject(rejectMessages.invalidParameters);
}
return this.loadImageFromURL(data.url, data.imageName);
}
/**
* Get the cropping rect
* @returns {Object} {{left: number, top: number, width: number, height: number}} rect
*/
}, {
key: 'getCropzoneRect',
value: function getCropzoneRect() {
return this._graphics.getCropzoneRect();
}
/**
* Flip
* @returns {Promise}
* @param {string} type - 'flipX' or 'flipY' or 'reset'
* @returns {Promise<FlipStatus, ErrorMsg>}
* @private
*/
}, {
key: '_flip',
value: function _flip(type) {
return this.execute(commands.FLIP_IMAGE, type);
}
/**
* Flip x
* @returns {Promise<FlipStatus, ErrorMsg>}
* @example
* imageEditor.flipX().then((status => {
* console.log('flipX: ', status.flipX);
* console.log('flipY: ', status.flipY);
* console.log('angle: ', status.angle);
* }).catch(message => {
* console.log('error: ', message);
* });
*/
}, {
key: 'flipX',
value: function flipX() {
return this._flip('flipX');
}
/**
* Flip y
* @returns {Promise<FlipStatus, ErrorMsg>}
* @example
* imageEditor.flipY().then(status => {
* console.log('flipX: ', status.flipX);
* console.log('flipY: ', status.flipY);
* console.log('angle: ', status.angle);
* }).catch(message => {
* console.log('error: ', message);
* });
*/
}, {
key: 'flipY',
value: function flipY() {
return this._flip('flipY');
}
/**
* Reset flip
* @returns {Promise<FlipStatus, ErrorMsg>}
* @example
* imageEditor.resetFlip().then(status => {
* console.log('flipX: ', status.flipX);
* console.log('flipY: ', status.flipY);
* console.log('angle: ', status.angle);
* }).catch(message => {
* console.log('error: ', message);
* });;
*/
}, {
key: 'resetFlip',
value: function resetFlip() {
return this._flip('reset');
}
/**
* @param {string} type - 'rotate' or 'setAngle'
* @param {number} angle - angle value (degree)
* @returns {Promise<RotateStatus, ErrorMsg>}
* @private
*/
}, {
key: '_rotate',
value: function _rotate(type, angle) {
return this.execute(commands.ROTATE_IMAGE, type, angle);
}
/**
* Rotate image
* @returns {Promise}
* @param {number} angle - Additional angle to rotate image
* @returns {Promise<RotateStatus, ErrorMsg>}
* @example
* imageEditor.setAngle(10); // angle = 10
* imageEditor.rotate(10); // angle = 20
* imageEidtor.setAngle(5); // angle = 5
* imageEidtor.rotate(-95); // angle = -90
* imageEditor.rotate(10).then(status => {
* console.log('angle: ', status.angle);
* })).catch(message => {
* console.log('error: ', message);
* });
*/
}, {
key: 'rotate',
value: function rotate(angle) {
return this._rotate('rotate', angle);
}
/**
* Set angle
* @param {number} angle - Angle of image
* @returns {Promise<RotateStatus, ErrorMsg>}
* @example
* imageEditor.setAngle(10); // angle = 10
* imageEditor.rotate(10); // angle = 20
* imageEidtor.setAngle(5); // angle = 5
* imageEidtor.rotate(50); // angle = 55
* imageEidtor.setAngle(-40); // angle = -40
* imageEditor.setAngle(10).then(status => {
* console.log('angle: ', status.angle);
* })).catch(message => {
* console.log('error: ', message);
* });
*/
}, {
key: 'setAngle',
value: function setAngle(angle) {
return this._rotate('setAngle', angle);
}
/**
* Set drawing brush
* @param {Object} option brush option
* @param {Number} option.width width
* @param {String} option.color color like 'FFFFFF', 'rgba(0, 0, 0, 0.5)'
* @example
* imageEditor.startDrawingMode('FREE_DRAWING');
* imageEditor.setBrush({
* width: 12,
* color: 'rgba(0, 0, 0, 0.5)'
* });
* imageEditor.setBrush({
* width: 8,
* color: 'FFFFFF'
* });
*/
}, {
key: 'setBrush',
value: function setBrush(option) {
this._graphics.setBrush(option);
}
/**
* Set states of current drawing shape
* @param {string} type - Shape type (ex: 'rect', 'circle', 'triangle')
* @param {Object} [options] - Shape options
* @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
* @param {string} [options.stoke] - Shape outline color
* @param {number} [options.strokeWidth] - Shape outline width
* @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
* @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
* @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
* @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
* @param {number} [options.isRegular] - Whether resizing shape has 1:1 ratio or not
* @example
* imageEditor.setDrawingShape('rect', {
* fill: 'red',
* width: 100,
* height: 200
* });
* @example
* imageEditor.setDrawingShape('circle', {
* fill: 'transparent',
* stroke: 'blue',
* strokeWidth: 3,
* rx: 10,
* ry: 100
* });
* @example
* imageEditor.setDrawingShape('triangle', { // When resizing, the shape keep the 1:1 ratio
* width: 1,
* height: 1,
* isRegular: true
* });
* @example
* imageEditor.setDrawingShape('circle', { // When resizing, the shape keep the 1:1 ratio
* rx: 10,
* ry: 10,
* isRegular: true
* });
*/
}, {
key: 'setDrawingShape',
value: function setDrawingShape(type, options) {
this._graphics.setDrawingShape(type, options);
}
/**
* Add shape
* @param {string} type - Shape type (ex: 'rect', 'circle', 'triangle')
* @param {Object} options - Shape options
* @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
* @param {string} [options.stroke] - Shape outline color
* @param {number} [options.strokeWidth] - Shape outline width
* @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
* @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
* @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
* @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
* @param {number} [options.left] - Shape x position
* @param {number} [options.top] - Shape y position
* @param {number} [options.isRegular] - Whether resizing shape has 1:1 ratio or not
* @returns {Promise<ObjectProps, ErrorMsg>}
* @example
* imageEditor.addShape('rect', {
* fill: 'red',
* stroke: 'blue',
* strokeWidth: 3,
* width: 100,
* height: 200,
* left: 10,
* top: 10,
* isRegular: true
* });
* @example
* imageEditor.addShape('circle', {
* fill: 'red',
* stroke: 'blue',
* strokeWidth: 3,
* rx: 10,
* ry: 100,
* isRegular: false
* }).then(objectProps => {
* console.log(objectProps.id);
* });
*/
}, {
key: 'addShape',
value: function addShape(type, options) {
options = options || {};
this._setPositions(options);
return this.execute(commands.ADD_SHAPE, type, options);
}
/**
* Change shape
* @param {number} id - object id
* @param {Object} options - Shape options
* @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
* @param {string} [options.stroke] - Shape outline color
* @param {number} [options.strokeWidth] - Shape outline width
* @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
* @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
* @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
* @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
* @param {number} [options.isRegular] - Whether resizing shape has 1:1 ratio or not
* @returns {Promise}
* @example
* // call after selecting shape object on canvas
* imageEditor.changeShape(id, { // change rectagle or triangle
* fill: 'red',
* stroke: 'blue',
* strokeWidth: 3,
* width: 100,
* height: 200
* });
* @example
* // call after selecting shape object on canvas
* imageEditor.changeShape(id, { // change circle
* fill: 'red',
* stroke: 'blue',
* strokeWidth: 3,
* rx: 10,
* ry: 100
* });
*/
}, {
key: 'changeShape',
value: function changeShape(id, options) {
return this.execute(commands.CHANGE_SHAPE, id, options);
}
/**
* Add text on image
* @param {string} text - Initial input text
* @param {Object} [options] Options for generating text
* @param {Object} [options.styles] Initial styles
* @param {string} [options.styles.fill] Color
* @param {string} [options.styles.fontFamily] Font type for text
* @param {number} [options.styles.fontSize] Size
* @param {string} [options.styles.fontStyle] Type of inclination (normal / italic)
* @param {string} [options.styles.fontWeight] Type of thicker or thinner looking (normal / bold)
* @param {string} [options.styles.textAlign] Type of text align (left / center / right)
* @param {string} [options.styles.textDecoraiton] Type of line (underline / line-throgh / overline)
* @param {{x: number, y: number}} [options.position] - Initial position
* @returns {Promise}
* @example
* imageEditor.addText('init text');
* @example
* imageEditor.addText('init text', {
* styles: {
* fill: '#000',
* fontSize: '20',
* fontWeight: 'bold'
* },
* position: {
* x: 10,
* y: 10
* }
* }).then(objectProps => {
* console.log(objectProps.id);
* });
*/
}, {
key: 'addText',
value: function addText(text, options) {
text = text || '';
options = options || {};
return this.execute(commands.ADD_TEXT, text, options);
}
}, {
key: 'addTexts',
value: function addTexts(configs) {
return this.execute(commands.ADD_TEXTS, configs);
}
/**
* Change contents of selected text object on image
* @param {number} id - object id
* @param {string} text - Changing text
* @returns {Promise<ObjectProps, ErrorMsg>}
* @example
* imageEditor.changeText(id, 'change text');
*/
}, {
key: 'changeText',
value: function changeText(id, text) {
text = text || '';
return this.execute(commands.CHANGE_TEXT, id, text);
}
/**
* Set style
* @param {number} id - object id
* @param {Object} styleObj - text styles
* @param {string} [styleObj.fill] Color
* @param {string} [styleObj.fontFamily] Font type for text
* @param {number} [styleObj.fontSize] Size
* @param {string} [styleObj.fontStyle] Type of inclination (normal / italic)
* @param {string} [styleObj.fontWeight] Type of thicker or thinner looking (normal / bold)
* @param {string} [styleObj.textAlign] Type of text align (left / center / right)
* @param {string} [styleObj.textDecoraiton] Type of line (underline / line-throgh / overline)
* @param {Boolean} notReset - reset flag
* @returns {Promise}
* @example
* imageEditor.changeTextStyle(id, {
* fontStyle: 'italic'
* });
*/
}, {
key: 'changeTextStyle',
value: function changeTextStyle(id, styleObj, notReset) {
return this.execute(commands.CHANGE_TEXT_STYLE, id, styleObj, notReset);
}
/**
* change text mode
* @param {string} type - change type
* @private
*/
}, {
key: '_changeActivateMode',
value: function _changeActivateMode(type) {
if (type !== 'ICON' && this.getDrawingMode() !== type) {
this.startDrawingMode(type);
}
}
/**
* 'textChanged' event handler
* @param {Object} objectProps changed object properties
* @private
*/
}, {
key: '_onTextChanged',
value: function _onTextChanged(objectProps) {
this.changeText(objectProps.id, objectProps.text);
}
/**
* 'iconCreateResize' event handler
* @param {Object} originPointer origin pointer
* @param {Number} originPointer.x x position
* @param {Number} originPointer.y y position
* @private
*/
}, {
key: '_onIconCreateResize',
value: function _onIconCreateResize(originPointer) {
this.fire(events.ICON_CREATE_RESIZE, originPointer);
}
/**
* 'iconCreateEnd' event handler
* @param {Object} originPointer origin pointer
* @param {Number} originPointer.x x position
* @param {Number} originPointer.y y position
* @private
*/
}, {
key: '_onIconCreateEnd',
value: function _onIconCreateEnd(originPointer) {
this.fire(events.ICON_CREATE_END, originPointer);
}
/**
* 'textEditing' event handler
* @param {target} target the editing target
* @private
*/
}, {
key: '_onTextEditing',
value: function _onTextEditing(target) {
/**
* The event which starts to edit text object
* @event ImageEditor#textEditing
* @example
* imageEditor.on('textEditing', function() {
* console.log('text editing');
* });
*/
this.fire(events.TEXT_EDITING, target);
}
/**
* Mousedown event handler in case of 'TEXT' drawing mode
* @param {fabric.Event} event - Current mousedown event object
* @private
*/
}, {
key: '_onAddText',
value: function _onAddText(event) {
/**
* The event when 'TEXT' drawing mode is enabled and click non-object area.
* @event ImageEditor#addText
* @param {Object} pos
* @param {Object} pos.originPosition - Current position on origin canvas
* @param {Number} pos.originPosition.x - x
* @param {Number} pos.originPosition.y - y
* @param {Object} pos.clientPosition - Current position on client area
* @param {Number} pos.clientPosition.x - x
* @param {Number} pos.clientPosition.y - y
* @example
* imageEditor.on('addText', function(pos) {
* imageEditor.addText('Double Click', {
* position: pos.originPosition
* });
* console.log('text position on canvas: ' + pos.originPosition);
* console.log('text position on brwoser: ' + pos.clientPosition);
* });
*/
this.fire(events.ADD_TEXT, {
originPosition: event.originPosition,
clientPosition: event.clientPosition
});
}
/**
* 'addObject' event handler
* @param {Object} objectProps added object properties
* @private
*/
}, {
key: '_onAddObject',
value: function _onAddObject(objectProps) {
var obj = this._graphics.getObject(objectProps.id);
this._pushAddObjectCommand(obj);
}
/**
* 'addObjectAfter' event handler
* @param {Object} objectProps added object properties
* @private
*/
}, {
key: '_onAddObjectAfter',
value: function _onAddObjectAfter(objectProps) {
this.fire(events.ADD_OBJECT_AFTER, objectProps);
}
/**
* 'selectionCleared' event handler
* @private
*/
}, {
key: '_selectionCleared',
value: function _selectionCleared() {
this.fire(events.SELECTION_CLEARED);
}
/**
* 'selectionCreated' event handler
* @param {Object} eventTarget - Fabric object
* @private
*/
}, {
key: '_selectionCreated',
value: function _selectionCreated(eventTarget) {
this.fire(events.SELECTION_CREATED, eventTarget);
}
/**
* Register custom icons
* @param {{iconType: string, pathValue: string}} infos - Infos to register icons
* @example
* imageEditor.registerIcons({
* customIcon: 'M 0 0 L 20 20 L 10 10 Z',
* customArrow: 'M 60 0 L 120 60 H 90 L 75 45 V 180 H 45 V 45 L 30 60 H 0 Z'
* });
*/
}, {
key: 'registerIcons',
value: function registerIcons(infos) {
this._graphics.registerPaths(infos);
}
/**
* Change canvas cursor type
* @param {string} cursorType - cursor type
* @example
* imageEditor.changeCursor('crosshair');
*/
}, {
key: 'changeCursor',
value: function changeCursor(cursorType) {
this._graphics.changeCursor(cursorType);
}
/**
* Add icon on canvas
* @param {string} type - Icon type ('arrow', 'cancel', custom icon name)
* @param {Object} options - Icon options
* @param {string} [options.fill] - Icon foreground color
* @param {string} [options.left] - Icon x position
* @param {string} [options.top] - Icon y position
* @returns {Promise<ObjectProps, ErrorMsg>}
* @example
* imageEditor.addIcon('arrow'); // The position is center on canvas
* @example
* imageEditor.addIcon('arrow', {
* left: 100,
* top: 100
* }).then(objectProps => {
* console.log(objectProps.id);
* });
*/
}, {
key: 'addIcon',
value: function addIcon(type, options) {
options = options || {};
this._setPositions(options);
return this.execute(commands.ADD_ICON, type, options);
}
/**
* Change icon color
* @param {number} id - object id
* @param {string} color - Color for icon
* @returns {Promise}
* @example
* imageEditor.changeIconColor(id, '#000000');
*/
}, {
key: 'changeIconColor',
value: function changeIconColor(id, color) {
return this.execute(commands.CHANGE_ICON_COLOR, id, color);
}
/**
* Remove an object or group by id
* @param {number} id - object id
* @returns {Promise}
* @example
* imageEditor.removeObject(id);
*/
}, {
key: 'removeObject',
value: function removeObject(id) {
return this.execute(commands.REMOVE_OBJECT, id);
}
/**
* Whether it has the filter or not
* @param {string} type - Filter type
* @returns {boolean} true if it has the filter
*/
}, {
key: 'hasFilter',
value: function hasFilter(type) {
return this._graphics.hasFilter(type);
}
/**
* Remove filter on canvas image
* @param {string} type - Filter type
* @returns {Promise<FilterResult, ErrorMsg>}
* @example
* imageEditor.removeFilter('Grayscale').then(obj => {
* console.log('filterType: ', obj.type);
* console.log('actType: ', obj.action);
* }).catch(message => {
* console.log('error: ', message);
* });
*/
}, {
key: 'removeFilter',
value: function removeFilter(type) {
return this.execute(commands.REMOVE_FILTER, type);
}
/**
* Apply filter on canvas image
* @param {string} type - Filter type
* @param {Object} options - Options to apply filter
* @param {number} options.maskObjId - masking image object id
* @returns {Promise<FilterResult, ErrorMsg>}
* @example
* imageEditor.applyFilter('Grayscale');
* @example
* imageEditor.applyFilter('mask', {maskObjId: id}).then(obj => {
* console.log('filterType: ', obj.type);
* console.log('actType: ', obj.action);
* }).catch(message => {
* console.log('error: ', message);
* });;
*/
}, {
key: 'applyFilter',
value: function applyFilter(type, options) {
return this.execute(commands.APPLY_FILTER, type, options);
}
/**
* Get data url
* @param {Object} options - options for toDataURL
* @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png"
* @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.
* @param {Number} [options.multiplier=1] Multiplier to scale by
* @param {Number} [options.left] Cropping left offset. Introduced in fabric v1.2.14
* @param {Number} [options.top] Cropping top offset. Introduced in fabric v1.2.14
* @param {Number} [options.width] Cropping width. Introduced in fabric v1.2.14
* @param {Number} [options.height] Cropping height. Introduced in fabric v1.2.14
* @returns {string} A DOMString containing the requested data URI
* @example
* imgEl.src = imageEditor.toDataURL();
*
* imageEditor.loadImageFromURL(imageEditor.toDataURL(), 'FilterImage').then(() => {
* imageEditor.addImageObject(imgUrl);
* });
*/
}, {
key: 'toDataURL',
value: function toDataURL(options) {
return this._graphics.toDataURL(options);
}
/**
* Get image name
* @returns {string} image name
* @example
* console.log(imageEditor.getImageName());
*/
}, {
key: 'getImageName',
value: function getImageName() {
return this._graphics.getImageName();
}
/**
* Clear undoStack
* @example
* imageEditor.clearUndoStack();
*/
}, {
key: 'clearUndoStack',
value: function clearUndoStack() {
this._invoker.clearUndoStack();
}
/**
* Clear redoStack
* @example
* imageEditor.clearRedoStack();
*/
}, {
key: 'clearRedoStack',
value: function clearRedoStack() {
this._invoker.clearRedoStack();
}
/**
* Whehter the undo stack is empty or not
* @returns {boolean}
* imageEditor.isEmptyUndoStack();
*/
}, {
key: 'isEmptyUndoStack',
value: function isEmptyUndoStack() {
return this._invoker.isEmptyUndoStack();
}
/**
* Whehter the redo stack is empty or not
* @returns {boolean}
* imageEditor.isEmptyRedoStack();
*/
}, {
key: 'isEmptyRedoStack',
value: function isEmptyRedoStack() {
return this._invoker.isEmptyRedoStack();
}
/**
* Resize canvas dimension
* @param {{width: number, height: number}} dimension - Max width & height
* @returns {Promise}
*/
}, {
key: 'resizeCanvasDimension',
value: function resizeCanvasDimension(dimension) {
if (!dimension) {
return _promise2.default.reject(rejectMessages.invalidParameters);
}
return this.execute(commands.RESIZE_CANVAS_DIMENSION, dimension);
}
/**
* Destroy
*/
}, {
key: 'destroy',
value: function destroy() {
var _this2 = this;
this.stopDrawingMode();
this._detachDomEvents();
this._graphics.destroy();
this._graphics = null;
forEach(this, function (value, key) {
_this2[key] = null;
}, this);
}
/**
* Set position
* @param {Object} options - Position options (left or top)
* @private
*/
}, {
key: '_setPositions',
value: function _setPositions(options) {
var centerPosition = this._graphics.getCenter();
if (isUndefined(options.left)) {
options.left = centerPosition.left;
}
if (isUndefined(options.top)) {
options.top = centerPosition.top;
}
}
/**
* Set properties of active object
* @param {number} id - object id
* @param {Object} keyValue - key & value
* @returns {Promise}
* @example
* imageEditor.setObjectProperties(id, {
* left:100,
* top:100,
* width: 200,
* height: 200,
* opacity: 0.5
* });
*/
}, {
key: 'setObjectProperties',
value: function setObjectProperties(id, keyValue) {
return this.execute(commands.SET_OBJECT_PROPERTIES, id, keyValue);
}
/**
* Set properties of active object, Do not leave an invoke history.
* @param {number} id - object id
* @param {Object} keyValue - key & value
* @example
* imageEditor.setObjectPropertiesQuietly(id, {
* left:100,
* top:100,
* width: 200,
* height: 200,
* opacity: 0.5
* });
*/
}, {
key: 'setObjectPropertiesQuietly',
value: function setObjectPropertiesQuietly(id, keyValue) {
this._graphics.setObjectProperties(id, keyValue);
}
/**
* Get properties of active object corresponding key
* @param {number} id - object id
* @param {Array<string>|ObjectProps|string} keys - property's key
* @returns {ObjectProps} properties if id is valid or null
* @example
* var props = imageEditor.getObjectProperties(id, 'left');
* console.log(props);
* @example
* var props = imageEditor.getObjectProperties(id, ['left', 'top', 'width', 'height']);
* console.log(props);
* @example
* var props = imageEditor.getObjectProperties(id, {
* left: null,
* top: null,
* width: null,
* height: null,
* opacity: null
* });
* console.log(props);
*/
}, {
key: 'getObjectProperties',
value: function getObjectProperties(id, keys) {
var object = this._graphics.getObject(id);
if (!object) {
return null;
}
return this._graphics.getObjectProperties(id, keys);
}
/**
* Get the canvas size
* @returns {Object} {{width: number, height: number}} canvas size
* @example
* var canvasSize = imageEditor.getCanvasSize();
* console.log(canvasSize.width);
* console.height(canvasSize.height);
*/
}, {
key: 'getCanvasSize',
value: function getCanvasSize() {
return this._graphics.getCanvasSize();
}
/**
* Get object position by originX, originY
* @param {number} id - object id
* @param {string} originX - can be 'left', 'center', 'right'
* @param {string} originY - can be 'top', 'center', 'bottom'
* @returns {Object} {{x:number, y: number}} position by origin if id is valid, or null
* @example
* var position = imageEditor.getObjectPosition(id, 'left', 'top');
* console.log(position);
*/
}, {
key: 'getObjectPosition',
value: function getObjectPosition(id, originX, originY) {
return this._graphics.getObjectPosition(id, originX, originY);
}
/**
* Set object position by originX, originY
* @param {number} id - object id
* @param {Object} posInfo - position object
* @param {number} posInfo.x - x position
* @param {number} posInfo.y - y position
* @param {string} posInfo.originX - can be 'left', 'center', 'right'
* @param {string} posInfo.originY - can be 'top', 'center', 'bottom'
* @returns {Promise}
* @example
* // align the object to 'left', 'top'
* imageEditor.setObjectPosition(id, {
* x: 0,
* y: 0,
* originX: 'left',
* originY: 'top'
* });
* @example
* // align the object to 'right', 'top'
* var canvasSize = imageEditor.getCanvasSize();
* imageEditor.setObjectPosition(id, {
* x: canvasSize.width,
* y: 0,
* originX: 'right',
* originY: 'top'
* });
* @example
* // align the object to 'left', 'bottom'
* var canvasSize = imageEditor.getCanvasSize();
* imageEditor.setObjectPosition(id, {
* x: 0,
* y: canvasSize.height,
* originX: 'left',
* originY: 'bottom'
* });
* @example
* // align the object to 'right', 'bottom'
* var canvasSize = imageEditor.getCanvasSize();
* imageEditor.setObjectPosition(id, {
* x: canvasSize.width,
* y: canvasSize.height,
* originX: 'right',
* originY: 'bottom'
* });
*/
}, {
key: 'setObjectPosition',
value: function setObjectPosition(id, posInfo) {
return this.execute(commands.SET_OBJECT_POSITION, id, posInfo);
}
}, {
key: 'setObjectPositions',
value: function setObjectPositions(settings) {
return this.execute(commands.SET_OBJECT_POSITIONS, settings);
}
}]);
return ImageEditor;
}();
_action2.default.mixin(ImageEditor);
CustomEvents.mixin(ImageEditor);
module.exports = ImageEditor;
/***/ }),
/* 3 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_3__;
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
__webpack_require__(5);
__webpack_require__(6);
__webpack_require__(50);
__webpack_require__(54);
module.exports = __webpack_require__(14).Promise;
/***/ }),
/* 5 */
/***/ (function(module, exports) {
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var $at = __webpack_require__(7)(true);
// 21.1.3.27 String.prototype[@@iterator]()
__webpack_require__(10)(String, 'String', function(iterated){
this._t = String(iterated); // target
this._i = 0; // next index
// 21.1.5.2.1 %StringIteratorPrototype%.next()
}, function(){
var O = this._t
, index = this._i
, point;
if(index >= O.length)return {value: undefined, done: true};
point = $at(O, index);
this._i += point.length;
return {value: point, done: false};
});
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
var toInteger = __webpack_require__(8)
, defined = __webpack_require__(9);
// true -> String#at
// false -> String#codePointAt
module.exports = function(TO_STRING){
return function(that, pos){
var s = String(defined(that))
, i = toInteger(pos)
, l = s.length
, a, b;
if(i < 0 || i >= l)return TO_STRING ? '' : undefined;
a = s.charCodeAt(i);
return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff
? TO_STRING ? s.charAt(i) : a
: TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
};
};
/***/ }),
/* 8 */
/***/ (function(module, exports) {
// 7.1.4 ToInteger
var ceil = Math.ceil
, floor = Math.floor;
module.exports = function(it){
return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
};
/***/ }),
/* 9 */
/***/ (function(module, exports) {
// 7.2.1 RequireObjectCoercible(argument)
module.exports = function(it){
if(it == undefined)throw TypeError("Can't call method on " + it);
return it;
};
/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var LIBRARY = __webpack_require__(11)
, $export = __webpack_require__(12)
, redefine = __webpack_require__(27)
, hide = __webpack_require__(17)
, has = __webpack_require__(28)
, Iterators = __webpack_require__(29)
, $iterCreate = __webpack_require__(30)
, setToStringTag = __webpack_require__(46)
, getPrototypeOf = __webpack_require__(48)
, ITERATOR = __webpack_require__(47)('iterator')
, BUGGY = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next`
, FF_ITERATOR = '@@iterator'
, KEYS = 'keys'
, VALUES = 'values';
var returnThis = function(){ return this; };
module.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){
$iterCreate(Constructor, NAME, next);
var getMethod = function(kind){
if(!BUGGY && kind in proto)return proto[kind];
switch(kind){
case KEYS: return function keys(){ return new Constructor(this, kind); };
case VALUES: return function values(){ return new Constructor(this, kind); };
} return function entries(){ return new Constructor(this, kind); };
};
var TAG = NAME + ' Iterator'
, DEF_VALUES = DEFAULT == VALUES
, VALUES_BUG = false
, proto = Base.prototype
, $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]
, $default = $native || getMethod(DEFAULT)
, $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined
, $anyNative = NAME == 'Array' ? proto.entries || $native : $native
, methods, key, IteratorPrototype;
// Fix native
if($anyNative){
IteratorPrototype = getPrototypeOf($anyNative.call(new Base));
if(IteratorPrototype !== Object.prototype){
// Set @@toStringTag to native iterators
setToStringTag(IteratorPrototype, TAG, true);
// fix for some old engines
if(!LIBRARY && !has(IteratorPrototype, ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis);
}
}
// fix Array#{values, @@iterator}.name in V8 / FF
if(DEF_VALUES && $native && $native.name !== VALUES){
VALUES_BUG = true;
$default = function values(){ return $native.call(this); };
}
// Define iterator
if((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){
hide(proto, ITERATOR, $default);
}
// Plug for library
Iterators[NAME] = $default;
Iterators[TAG] = returnThis;
if(DEFAULT){
methods = {
values: DEF_VALUES ? $default : getMethod(VALUES),
keys: IS_SET ? $default : getMethod(KEYS),
entries: $entries
};
if(FORCED)for(key in methods){
if(!(key in proto))redefine(proto, key, methods[key]);
} else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);
}
return methods;
};
/***/ }),
/* 11 */
/***/ (function(module, exports) {
module.exports = true;
/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {
var global = __webpack_require__(13)
, core = __webpack_require__(14)
, ctx = __webpack_require__(15)
, hide = __webpack_require__(17)
, PROTOTYPE = 'prototype';
var $export = function(type, name, source){
var IS_FORCED = type & $export.F
, IS_GLOBAL = type & $export.G
, IS_STATIC = type & $export.S
, IS_PROTO = type & $export.P
, IS_BIND = type & $export.B
, IS_WRAP = type & $export.W
, exports = IS_GLOBAL ? core : core[name] || (core[name] = {})
, expProto = exports[PROTOTYPE]
, target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]
, key, own, out;
if(IS_GLOBAL)source = name;
for(key in source){
// contains in native
own = !IS_FORCED && target && target[key] !== undefined;
if(own && key in exports)continue;
// export native or passed
out = own ? target[key] : source[key];
// prevent global pollution for namespaces
exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]
// bind timers to global for call from export context
: IS_BIND && own ? ctx(out, global)
// wrap global constructors for prevent change them in library
: IS_WRAP && target[key] == out ? (function(C){
var F = function(a, b, c){
if(this instanceof C){
switch(arguments.length){
case 0: return new C;
case 1: return new C(a);
case 2: return new C(a, b);
} return new C(a, b, c);
} return C.apply(this, arguments);
};
F[PROTOTYPE] = C[PROTOTYPE];
return F;
// make static versions for prototype methods
})(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
// export proto methods to core.%CONSTRUCTOR%.methods.%NAME%
if(IS_PROTO){
(exports.virtual || (exports.virtual = {}))[key] = out;
// export proto methods to core.%CONSTRUCTOR%.prototype.%NAME%
if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out);
}
}
};
// type bitmap
$export.F = 1; // forced
$export.G = 2; // global
$export.S = 4; // static
$export.P = 8; // proto
$export.B = 16; // bind
$export.W = 32; // wrap
$export.U = 64; // safe
$export.R = 128; // real proto method for `library`
module.exports = $export;
/***/ }),
/* 13 */
/***/ (function(module, exports) {
// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
var global = module.exports = typeof window != 'undefined' && window.Math == Math
? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();
if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef
/***/ }),
/* 14 */
/***/ (function(module, exports) {
var core = module.exports = {version: '2.4.0'};
if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef
/***/ }),
/* 15 */
/***/ (function(module, exports, __webpack_require__) {
// optional / simple context binding
var aFunction = __webpack_require__(16);
module.exports = function(fn, that, length){
aFunction(fn);
if(that === undefined)return fn;
switch(length){
case 1: return function(a){
return fn.call(that, a);
};
case 2: return function(a, b){
return fn.call(that, a, b);
};
case 3: return function(a, b, c){
return fn.call(that, a, b, c);
};
}
return function(/* ...args */){
return fn.apply(that, arguments);
};
};
/***/ }),
/* 16 */
/***/ (function(module, exports) {
module.exports = function(it){
if(typeof it != 'function')throw TypeError(it + ' is not a function!');
return it;
};
/***/ }),
/* 17 */
/***/ (function(module, exports, __webpack_require__) {
var dP = __webpack_require__(18)
, createDesc = __webpack_require__(26);
module.exports = __webpack_require__(22) ? function(object, key, value){
return dP.f(object, key, createDesc(1, value));
} : function(object, key, value){
object[key] = value;
return object;
};
/***/ }),
/* 18 */
/***/ (function(module, exports, __webpack_require__) {
var anObject = __webpack_require__(19)
, IE8_DOM_DEFINE = __webpack_require__(21)
, toPrimitive = __webpack_require__(25)
, dP = Object.defineProperty;
exports.f = __webpack_require__(22) ? Object.defineProperty : function defineProperty(O, P, Attributes){
anObject(O);
P = toPrimitive(P, true);
anObject(Attributes);
if(IE8_DOM_DEFINE)try {
return dP(O, P, Attributes);
} catch(e){ /* empty */ }
if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!');
if('value' in Attributes)O[P] = Attributes.value;
return O;
};
/***/ }),
/* 19 */
/***/ (function(module, exports, __webpack_require__) {
var isObject = __webpack_require__(20);
module.exports = function(it){
if(!isObject(it))throw TypeError(it + ' is not an object!');
return it;
};
/***/ }),
/* 20 */
/***/ (function(module, exports) {
module.exports = function(it){
return typeof it === 'object' ? it !== null : typeof it === 'function';
};
/***/ }),
/* 21 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = !__webpack_require__(22) && !__webpack_require__(23)(function(){
return Object.defineProperty(__webpack_require__(24)('div'), 'a', {get: function(){ return 7; }}).a != 7;
});
/***/ }),
/* 22 */
/***/ (function(module, exports, __webpack_require__) {
// Thank's IE8 for his funny defineProperty
module.exports = !__webpack_require__(23)(function(){
return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;
});
/***/ }),
/* 23 */
/***/ (function(module, exports) {
module.exports = function(exec){
try {
return !!exec();
} catch(e){
return true;
}
};
/***/ }),
/* 24 */
/***/ (function(module, exports, __webpack_require__) {
var isObject = __webpack_require__(20)
, document = __webpack_require__(13).document
// in old IE typeof document.createElement is 'object'
, is = isObject(document) && isObject(document.createElement);
module.exports = function(it){
return is ? document.createElement(it) : {};
};
/***/ }),
/* 25 */
/***/ (function(module, exports, __webpack_require__) {
// 7.1.1 ToPrimitive(input [, PreferredType])
var isObject = __webpack_require__(20);
// instead of the ES6 spec version, we didn't implement @@toPrimitive case
// and the second argument - flag - preferred type is a string
module.exports = function(it, S){
if(!isObject(it))return it;
var fn, val;
if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;
if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val;
if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;
throw TypeError("Can't convert object to primitive value");
};
/***/ }),
/* 26 */
/***/ (function(module, exports) {
module.exports = function(bitmap, value){
return {
enumerable : !(bitmap & 1),
configurable: !(bitmap & 2),
writable : !(bitmap & 4),
value : value
};
};
/***/ }),
/* 27 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(17);
/***/ }),
/* 28 */
/***/ (function(module, exports) {
var hasOwnProperty = {}.hasOwnProperty;
module.exports = function(it, key){
return hasOwnProperty.call(it, key);
};
/***/ }),
/* 29 */
/***/ (function(module, exports) {
module.exports = {};
/***/ }),
/* 30 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var create = __webpack_require__(31)
, descriptor = __webpack_require__(26)
, setToStringTag = __webpack_require__(46)
, IteratorPrototype = {};
// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
__webpack_require__(17)(IteratorPrototype, __webpack_require__(47)('iterator'), function(){ return this; });
module.exports = function(Constructor, NAME, next){
Constructor.prototype = create(IteratorPrototype, {next: descriptor(1, next)});
setToStringTag(Constructor, NAME + ' Iterator');
};
/***/ }),
/* 31 */
/***/ (function(module, exports, __webpack_require__) {
// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
var anObject = __webpack_require__(19)
, dPs = __webpack_require__(32)
, enumBugKeys = __webpack_require__(44)
, IE_PROTO = __webpack_require__(41)('IE_PROTO')
, Empty = function(){ /* empty */ }
, PROTOTYPE = 'prototype';
// Create object with fake `null` prototype: use iframe Object with cleared prototype
var createDict = function(){
// Thrash, waste and sodomy: IE GC bug
var iframe = __webpack_require__(24)('iframe')
, i = enumBugKeys.length
, lt = '<'
, gt = '>'
, iframeDocument;
iframe.style.display = 'none';
__webpack_require__(45).appendChild(iframe);
iframe.src = 'javascript:'; // eslint-disable-line no-script-url
// createDict = iframe.contentWindow.Object;
// html.removeChild(iframe);
iframeDocument = iframe.contentWindow.document;
iframeDocument.open();
iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);
iframeDocument.close();
createDict = iframeDocument.F;
while(i--)delete createDict[PROTOTYPE][enumBugKeys[i]];
return createDict();
};
module.exports = Object.create || function create(O, Properties){
var result;
if(O !== null){
Empty[PROTOTYPE] = anObject(O);
result = new Empty;
Empty[PROTOTYPE] = null;
// add "__proto__" for Object.getPrototypeOf polyfill
result[IE_PROTO] = O;
} else result = createDict();
return Properties === undefined ? result : dPs(result, Properties);
};
/***/ }),
/* 32 */
/***/ (function(module, exports, __webpack_require__) {
var dP = __webpack_require__(18)
, anObject = __webpack_require__(19)
, getKeys = __webpack_require__(33);
module.exports = __webpack_require__(22) ? Object.defineProperties : function defineProperties(O, Properties){
anObject(O);
var keys = getKeys(Properties)
, length = keys.length
, i = 0
, P;
while(length > i)dP.f(O, P = keys[i++], Properties[P]);
return O;
};
/***/ }),
/* 33 */
/***/ (function(module, exports, __webpack_require__) {
// 19.1.2.14 / 15.2.3.14 Object.keys(O)
var $keys = __webpack_require__(34)
, enumBugKeys = __webpack_require__(44);
module.exports = Object.keys || function keys(O){
return $keys(O, enumBugKeys);
};
/***/ }),
/* 34 */
/***/ (function(module, exports, __webpack_require__) {
var has = __webpack_require__(28)
, toIObject = __webpack_require__(35)
, arrayIndexOf = __webpack_require__(38)(false)
, IE_PROTO = __webpack_require__(41)('IE_PROTO');
module.exports = function(object, names){
var O = toIObject(object)
, i = 0
, result = []
, key;
for(key in O)if(key != IE_PROTO)has(O, key) && result.push(key);
// Don't enum bug & hidden keys
while(names.length > i)if(has(O, key = names[i++])){
~arrayIndexOf(result, key) || result.push(key);
}
return result;
};
/***/ }),
/* 35 */
/***/ (function(module, exports, __webpack_require__) {
// to indexed object, toObject with fallback for non-array-like ES3 strings
var IObject = __webpack_require__(36)
, defined = __webpack_require__(9);
module.exports = function(it){
return IObject(defined(it));
};
/***/ }),
/* 36 */
/***/ (function(module, exports, __webpack_require__) {
// fallback for non-array-like ES3 and non-enumerable old V8 strings
var cof = __webpack_require__(37);
module.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){
return cof(it) == 'String' ? it.split('') : Object(it);
};
/***/ }),
/* 37 */
/***/ (function(module, exports) {
var toString = {}.toString;
module.exports = function(it){
return toString.call(it).slice(8, -1);
};
/***/ }),
/* 38 */
/***/ (function(module, exports, __webpack_require__) {
// false -> Array#indexOf
// true -> Array#includes
var toIObject = __webpack_require__(35)
, toLength = __webpack_require__(39)
, toIndex = __webpack_require__(40);
module.exports = function(IS_INCLUDES){
return function($this, el, fromIndex){
var O = toIObject($this)
, length = toLength(O.length)
, index = toIndex(fromIndex, length)
, value;
// Array#includes uses SameValueZero equality algorithm
if(IS_INCLUDES && el != el)while(length > index){
value = O[index++];
if(value != value)return true;
// Array#toIndex ignores holes, Array#includes - not
} else for(;length > index; index++)if(IS_INCLUDES || index in O){
if(O[index] === el)return IS_INCLUDES || index || 0;
} return !IS_INCLUDES && -1;
};
};
/***/ }),
/* 39 */
/***/ (function(module, exports, __webpack_require__) {
// 7.1.15 ToLength
var toInteger = __webpack_require__(8)
, min = Math.min;
module.exports = function(it){
return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
};
/***/ }),
/* 40 */
/***/ (function(module, exports, __webpack_require__) {
var toInteger = __webpack_require__(8)
, max = Math.max
, min = Math.min;
module.exports = function(index, length){
index = toInteger(index);
return index < 0 ? max(index + length, 0) : min(index, length);
};
/***/ }),
/* 41 */
/***/ (function(module, exports, __webpack_require__) {
var shared = __webpack_require__(42)('keys')
, uid = __webpack_require__(43);
module.exports = function(key){
return shared[key] || (shared[key] = uid(key));
};
/***/ }),
/* 42 */
/***/ (function(module, exports, __webpack_require__) {
var global = __webpack_require__(13)
, SHARED = '__core-js_shared__'
, store = global[SHARED] || (global[SHARED] = {});
module.exports = function(key){
return store[key] || (store[key] = {});
};
/***/ }),
/* 43 */
/***/ (function(module, exports) {
var id = 0
, px = Math.random();
module.exports = function(key){
return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
};
/***/ }),
/* 44 */
/***/ (function(module, exports) {
// IE 8- don't enum bug keys
module.exports = (
'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'
).split(',');
/***/ }),
/* 45 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(13).document && document.documentElement;
/***/ }),
/* 46 */
/***/ (function(module, exports, __webpack_require__) {
var def = __webpack_require__(18).f
, has = __webpack_require__(28)
, TAG = __webpack_require__(47)('toStringTag');
module.exports = function(it, tag, stat){
if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag});
};
/***/ }),
/* 47 */
/***/ (function(module, exports, __webpack_require__) {
var store = __webpack_require__(42)('wks')
, uid = __webpack_require__(43)
, Symbol = __webpack_require__(13).Symbol
, USE_SYMBOL = typeof Symbol == 'function';
var $exports = module.exports = function(name){
return store[name] || (store[name] =
USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));
};
$exports.store = store;
/***/ }),
/* 48 */
/***/ (function(module, exports, __webpack_require__) {
// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)
var has = __webpack_require__(28)
, toObject = __webpack_require__(49)
, IE_PROTO = __webpack_require__(41)('IE_PROTO')
, ObjectProto = Object.prototype;
module.exports = Object.getPrototypeOf || function(O){
O = toObject(O);
if(has(O, IE_PROTO))return O[IE_PROTO];
if(typeof O.constructor == 'function' && O instanceof O.constructor){
return O.constructor.prototype;
} return O instanceof Object ? ObjectProto : null;
};
/***/ }),
/* 49 */
/***/ (function(module, exports, __webpack_require__) {
// 7.1.13 ToObject(argument)
var defined = __webpack_require__(9);
module.exports = function(it){
return Object(defined(it));
};
/***/ }),
/* 50 */
/***/ (function(module, exports, __webpack_require__) {
__webpack_require__(51);
var global = __webpack_require__(13)
, hide = __webpack_require__(17)
, Iterators = __webpack_require__(29)
, TO_STRING_TAG = __webpack_require__(47)('toStringTag');
for(var collections = ['NodeList', 'DOMTokenList', 'MediaList', 'StyleSheetList', 'CSSRuleList'], i = 0; i < 5; i++){
var NAME = collections[i]
, Collection = global[NAME]
, proto = Collection && Collection.prototype;
if(proto && !proto[TO_STRING_TAG])hide(proto, TO_STRING_TAG, NAME);
Iterators[NAME] = Iterators.Array;
}
/***/ }),
/* 51 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var addToUnscopables = __webpack_require__(52)
, step = __webpack_require__(53)
, Iterators = __webpack_require__(29)
, toIObject = __webpack_require__(35);
// 22.1.3.4 Array.prototype.entries()
// 22.1.3.13 Array.prototype.keys()
// 22.1.3.29 Array.prototype.values()
// 22.1.3.30 Array.prototype[@@iterator]()
module.exports = __webpack_require__(10)(Array, 'Array', function(iterated, kind){
this._t = toIObject(iterated); // target
this._i = 0; // next index
this._k = kind; // kind
// 22.1.5.2.1 %ArrayIteratorPrototype%.next()
}, function(){
var O = this._t
, kind = this._k
, index = this._i++;
if(!O || index >= O.length){
this._t = undefined;
return step(1);
}
if(kind == 'keys' )return step(0, index);
if(kind == 'values')return step(0, O[index]);
return step(0, [index, O[index]]);
}, 'values');
// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
Iterators.Arguments = Iterators.Array;
addToUnscopables('keys');
addToUnscopables('values');
addToUnscopables('entries');
/***/ }),
/* 52 */
/***/ (function(module, exports) {
module.exports = function(){ /* empty */ };
/***/ }),
/* 53 */
/***/ (function(module, exports) {
module.exports = function(done, value){
return {value: value, done: !!done};
};
/***/ }),
/* 54 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var LIBRARY = __webpack_require__(11)
, global = __webpack_require__(13)
, ctx = __webpack_require__(15)
, classof = __webpack_require__(55)
, $export = __webpack_require__(12)
, isObject = __webpack_require__(20)
, aFunction = __webpack_require__(16)
, anInstance = __webpack_require__(56)
, forOf = __webpack_require__(57)
, speciesConstructor = __webpack_require__(61)
, task = __webpack_require__(62).set
, microtask = __webpack_require__(64)()
, PROMISE = 'Promise'
, TypeError = global.TypeError
, process = global.process
, $Promise = global[PROMISE]
, process = global.process
, isNode = classof(process) == 'process'
, empty = function(){ /* empty */ }
, Internal, GenericPromiseCapability, Wrapper;
var USE_NATIVE = !!function(){
try {
// correct subclassing with @@species support
var promise = $Promise.resolve(1)
, FakePromise = (promise.constructor = {})[__webpack_require__(47)('species')] = function(exec){ exec(empty, empty); };
// unhandled rejections tracking support, NodeJS Promise without it fails @@species test
return (isNode || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise;
} catch(e){ /* empty */ }
}();
// helpers
var sameConstructor = function(a, b){
// with library wrapper special case
return a === b || a === $Promise && b === Wrapper;
};
var isThenable = function(it){
var then;
return isObject(it) && typeof (then = it.then) == 'function' ? then : false;
};
var newPromiseCapability = function(C){
return sameConstructor($Promise, C)
? new PromiseCapability(C)
: new GenericPromiseCapability(C);
};
var PromiseCapability = GenericPromiseCapability = function(C){
var resolve, reject;
this.promise = new C(function($$resolve, $$reject){
if(resolve !== undefined || reject !== undefined)throw TypeError('Bad Promise constructor');
resolve = $$resolve;
reject = $$reject;
});
this.resolve = aFunction(resolve);
this.reject = aFunction(reject);
};
var perform = function(exec){
try {
exec();
} catch(e){
return {error: e};
}
};
var notify = function(promise, isReject){
if(promise._n)return;
promise._n = true;
var chain = promise._c;
microtask(function(){
var value = promise._v
, ok = promise._s == 1
, i = 0;
var run = function(reaction){
var handler = ok ? reaction.ok : reaction.fail
, resolve = reaction.resolve
, reject = reaction.reject
, domain = reaction.domain
, result, then;
try {
if(handler){
if(!ok){
if(promise._h == 2)onHandleUnhandled(promise);
promise._h = 1;
}
if(handler === true)result = value;
else {
if(domain)domain.enter();
result = handler(value);
if(domain)domain.exit();
}
if(result === reaction.promise){
reject(TypeError('Promise-chain cycle'));
} else if(then = isThenable(result)){
then.call(result, resolve, reject);
} else resolve(result);
} else reject(value);
} catch(e){
reject(e);
}
};
while(chain.length > i)run(chain[i++]); // variable length - can't use forEach
promise._c = [];
promise._n = false;
if(isReject && !promise._h)onUnhandled(promise);
});
};
var onUnhandled = function(promise){
task.call(global, function(){
var value = promise._v
, abrupt, handler, console;
if(isUnhandled(promise)){
abrupt = perform(function(){
if(isNode){
process.emit('unhandledRejection', value, promise);
} else if(handler = global.onunhandledrejection){
handler({promise: promise, reason: value});
} else if((console = global.console) && console.error){
console.error('Unhandled promise rejection', value);
}
});
// Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should
promise._h = isNode || isUnhandled(promise) ? 2 : 1;
} promise._a = undefined;
if(abrupt)throw abrupt.error;
});
};
var isUnhandled = function(promise){
if(promise._h == 1)return false;
var chain = promise._a || promise._c
, i = 0
, reaction;
while(chain.length > i){
reaction = chain[i++];
if(reaction.fail || !isUnhandled(reaction.promise))return false;
} return true;
};
var onHandleUnhandled = function(promise){
task.call(global, function(){
var handler;
if(isNode){
process.emit('rejectionHandled', promise);
} else if(handler = global.onrejectionhandled){
handler({promise: promise, reason: promise._v});
}
});
};
var $reject = function(value){
var promise = this;
if(promise._d)return;
promise._d = true;
promise = promise._w || promise; // unwrap
promise._v = value;
promise._s = 2;
if(!promise._a)promise._a = promise._c.slice();
notify(promise, true);
};
var $resolve = function(value){
var promise = this
, then;
if(promise._d)return;
promise._d = true;
promise = promise._w || promise; // unwrap
try {
if(promise === value)throw TypeError("Promise can't be resolved itself");
if(then = isThenable(value)){
microtask(function(){
var wrapper = {_w: promise, _d: false}; // wrap
try {
then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));
} catch(e){
$reject.call(wrapper, e);
}
});
} else {
promise._v = value;
promise._s = 1;
notify(promise, false);
}
} catch(e){
$reject.call({_w: promise, _d: false}, e); // wrap
}
};
// constructor polyfill
if(!USE_NATIVE){
// 25.4.3.1 Promise(executor)
$Promise = function Promise(executor){
anInstance(this, $Promise, PROMISE, '_h');
aFunction(executor);
Internal.call(this);
try {
executor(ctx($resolve, this, 1), ctx($reject, this, 1));
} catch(err){
$reject.call(this, err);
}
};
Internal = function Promise(executor){
this._c = []; // <- awaiting reactions
this._a = undefined; // <- checked in isUnhandled reactions
this._s = 0; // <- state
this._d = false; // <- done
this._v = undefined; // <- value
this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled
this._n = false; // <- notify
};
Internal.prototype = __webpack_require__(65)($Promise.prototype, {
// 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)
then: function then(onFulfilled, onRejected){
var reaction = newPromiseCapability(speciesConstructor(this, $Promise));
reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;
reaction.fail = typeof onRejected == 'function' && onRejected;
reaction.domain = isNode ? process.domain : undefined;
this._c.push(reaction);
if(this._a)this._a.push(reaction);
if(this._s)notify(this, false);
return reaction.promise;
},
// 25.4.5.1 Promise.prototype.catch(onRejected)
'catch': function(onRejected){
return this.then(undefined, onRejected);
}
});
PromiseCapability = function(){
var promise = new Internal;
this.promise = promise;
this.resolve = ctx($resolve, promise, 1);
this.reject = ctx($reject, promise, 1);
};
}
$export($export.G + $export.W + $export.F * !USE_NATIVE, {Promise: $Promise});
__webpack_require__(46)($Promise, PROMISE);
__webpack_require__(66)(PROMISE);
Wrapper = __webpack_require__(14)[PROMISE];
// statics
$export($export.S + $export.F * !USE_NATIVE, PROMISE, {
// 25.4.4.5 Promise.reject(r)
reject: function reject(r){
var capability = newPromiseCapability(this)
, $$reject = capability.reject;
$$reject(r);
return capability.promise;
}
});
$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, {
// 25.4.4.6 Promise.resolve(x)
resolve: function resolve(x){
// instanceof instead of internal slot check because we should fix it without replacement native Promise core
if(x instanceof $Promise && sameConstructor(x.constructor, this))return x;
var capability = newPromiseCapability(this)
, $$resolve = capability.resolve;
$$resolve(x);
return capability.promise;
}
});
$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(67)(function(iter){
$Promise.all(iter)['catch'](empty);
})), PROMISE, {
// 25.4.4.1 Promise.all(iterable)
all: function all(iterable){
var C = this
, capability = newPromiseCapability(C)
, resolve = capability.resolve
, reject = capability.reject;
var abrupt = perform(function(){
var values = []
, index = 0
, remaining = 1;
forOf(iterable, false, function(promise){
var $index = index++
, alreadyCalled = false;
values.push(undefined);
remaining++;
C.resolve(promise).then(function(value){
if(alreadyCalled)return;
alreadyCalled = true;
values[$index] = value;
--remaining || resolve(values);
}, reject);
});
--remaining || resolve(values);
});
if(abrupt)reject(abrupt.error);
return capability.promise;
},
// 25.4.4.4 Promise.race(iterable)
race: function race(iterable){
var C = this
, capability = newPromiseCapability(C)
, reject = capability.reject;
var abrupt = perform(function(){
forOf(iterable, false, function(promise){
C.resolve(promise).then(capability.resolve, reject);
});
});
if(abrupt)reject(abrupt.error);
return capability.promise;
}
});
/***/ }),
/* 55 */
/***/ (function(module, exports, __webpack_require__) {
// getting tag from 19.1.3.6 Object.prototype.toString()
var cof = __webpack_require__(37)
, TAG = __webpack_require__(47)('toStringTag')
// ES3 wrong here
, ARG = cof(function(){ return arguments; }()) == 'Arguments';
// fallback for IE11 Script Access Denied error
var tryGet = function(it, key){
try {
return it[key];
} catch(e){ /* empty */ }
};
module.exports = function(it){
var O, T, B;
return it === undefined ? 'Undefined' : it === null ? 'Null'
// @@toStringTag case
: typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T
// builtinTag case
: ARG ? cof(O)
// ES3 arguments fallback
: (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
};
/***/ }),
/* 56 */
/***/ (function(module, exports) {
module.exports = function(it, Constructor, name, forbiddenField){
if(!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)){
throw TypeError(name + ': incorrect invocation!');
} return it;
};
/***/ }),
/* 57 */
/***/ (function(module, exports, __webpack_require__) {
var ctx = __webpack_require__(15)
, call = __webpack_require__(58)
, isArrayIter = __webpack_require__(59)
, anObject = __webpack_require__(19)
, toLength = __webpack_require__(39)
, getIterFn = __webpack_require__(60)
, BREAK = {}
, RETURN = {};
var exports = module.exports = function(iterable, entries, fn, that, ITERATOR){
var iterFn = ITERATOR ? function(){ return iterable; } : getIterFn(iterable)
, f = ctx(fn, that, entries ? 2 : 1)
, index = 0
, length, step, iterator, result;
if(typeof iterFn != 'function')throw TypeError(iterable + ' is not iterable!');
// fast case for arrays with default iterator
if(isArrayIter(iterFn))for(length = toLength(iterable.length); length > index; index++){
result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);
if(result === BREAK || result === RETURN)return result;
} else for(iterator = iterFn.call(iterable); !(step = iterator.next()).done; ){
result = call(iterator, f, step.value, entries);
if(result === BREAK || result === RETURN)return result;
}
};
exports.BREAK = BREAK;
exports.RETURN = RETURN;
/***/ }),
/* 58 */
/***/ (function(module, exports, __webpack_require__) {
// call something on iterator step with safe closing on error
var anObject = __webpack_require__(19);
module.exports = function(iterator, fn, value, entries){
try {
return entries ? fn(anObject(value)[0], value[1]) : fn(value);
// 7.4.6 IteratorClose(iterator, completion)
} catch(e){
var ret = iterator['return'];
if(ret !== undefined)anObject(ret.call(iterator));
throw e;
}
};
/***/ }),
/* 59 */
/***/ (function(module, exports, __webpack_require__) {
// check on default Array iterator
var Iterators = __webpack_require__(29)
, ITERATOR = __webpack_require__(47)('iterator')
, ArrayProto = Array.prototype;
module.exports = function(it){
return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);
};
/***/ }),
/* 60 */
/***/ (function(module, exports, __webpack_require__) {
var classof = __webpack_require__(55)
, ITERATOR = __webpack_require__(47)('iterator')
, Iterators = __webpack_require__(29);
module.exports = __webpack_require__(14).getIteratorMethod = function(it){
if(it != undefined)return it[ITERATOR]
|| it['@@iterator']
|| Iterators[classof(it)];
};
/***/ }),
/* 61 */
/***/ (function(module, exports, __webpack_require__) {
// 7.3.20 SpeciesConstructor(O, defaultConstructor)
var anObject = __webpack_require__(19)
, aFunction = __webpack_require__(16)
, SPECIES = __webpack_require__(47)('species');
module.exports = function(O, D){
var C = anObject(O).constructor, S;
return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);
};
/***/ }),
/* 62 */
/***/ (function(module, exports, __webpack_require__) {
var ctx = __webpack_require__(15)
, invoke = __webpack_require__(63)
, html = __webpack_require__(45)
, cel = __webpack_require__(24)
, global = __webpack_require__(13)
, process = global.process
, setTask = global.setImmediate
, clearTask = global.clearImmediate
, MessageChannel = global.MessageChannel
, counter = 0
, queue = {}
, ONREADYSTATECHANGE = 'onreadystatechange'
, defer, channel, port;
var run = function(){
var id = +this;
if(queue.hasOwnProperty(id)){
var fn = queue[id];
delete queue[id];
fn();
}
};
var listener = function(event){
run.call(event.data);
};
// Node.js 0.9+ & IE10+ has setImmediate, otherwise:
if(!setTask || !clearTask){
setTask = function setImmediate(fn){
var args = [], i = 1;
while(arguments.length > i)args.push(arguments[i++]);
queue[++counter] = function(){
invoke(typeof fn == 'function' ? fn : Function(fn), args);
};
defer(counter);
return counter;
};
clearTask = function clearImmediate(id){
delete queue[id];
};
// Node.js 0.8-
if(__webpack_require__(37)(process) == 'process'){
defer = function(id){
process.nextTick(ctx(run, id, 1));
};
// Browsers with MessageChannel, includes WebWorkers
} else if(MessageChannel){
channel = new MessageChannel;
port = channel.port2;
channel.port1.onmessage = listener;
defer = ctx(port.postMessage, port, 1);
// Browsers with postMessage, skip WebWorkers
// IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
} else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){
defer = function(id){
global.postMessage(id + '', '*');
};
global.addEventListener('message', listener, false);
// IE8-
} else if(ONREADYSTATECHANGE in cel('script')){
defer = function(id){
html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){
html.removeChild(this);
run.call(id);
};
};
// Rest old browsers
} else {
defer = function(id){
setTimeout(ctx(run, id, 1), 0);
};
}
}
module.exports = {
set: setTask,
clear: clearTask
};
/***/ }),
/* 63 */
/***/ (function(module, exports) {
// fast apply, http://jsperf.lnkit.com/fast-apply/5
module.exports = function(fn, args, that){
var un = that === undefined;
switch(args.length){
case 0: return un ? fn()
: fn.call(that);
case 1: return un ? fn(args[0])
: fn.call(that, args[0]);
case 2: return un ? fn(args[0], args[1])
: fn.call(that, args[0], args[1]);
case 3: return un ? fn(args[0], args[1], args[2])
: fn.call(that, args[0], args[1], args[2]);
case 4: return un ? fn(args[0], args[1], args[2], args[3])
: fn.call(that, args[0], args[1], args[2], args[3]);
} return fn.apply(that, args);
};
/***/ }),
/* 64 */
/***/ (function(module, exports, __webpack_require__) {
var global = __webpack_require__(13)
, macrotask = __webpack_require__(62).set
, Observer = global.MutationObserver || global.WebKitMutationObserver
, process = global.process
, Promise = global.Promise
, isNode = __webpack_require__(37)(process) == 'process';
module.exports = function(){
var head, last, notify;
var flush = function(){
var parent, fn;
if(isNode && (parent = process.domain))parent.exit();
while(head){
fn = head.fn;
head = head.next;
try {
fn();
} catch(e){
if(head)notify();
else last = undefined;
throw e;
}
} last = undefined;
if(parent)parent.enter();
};
// Node.js
if(isNode){
notify = function(){
process.nextTick(flush);
};
// browsers with MutationObserver
} else if(Observer){
var toggle = true
, node = document.createTextNode('');
new Observer(flush).observe(node, {characterData: true}); // eslint-disable-line no-new
notify = function(){
node.data = toggle = !toggle;
};
// environments with maybe non-completely correct, but existent Promise
} else if(Promise && Promise.resolve){
var promise = Promise.resolve();
notify = function(){
promise.then(flush);
};
// for other environments - macrotask based on:
// - setImmediate
// - MessageChannel
// - window.postMessag
// - onreadystatechange
// - setTimeout
} else {
notify = function(){
// strange IE + webpack dev server bug - use .call(global)
macrotask.call(global, flush);
};
}
return function(fn){
var task = {fn: fn, next: undefined};
if(last)last.next = task;
if(!head){
head = task;
notify();
} last = task;
};
};
/***/ }),
/* 65 */
/***/ (function(module, exports, __webpack_require__) {
var hide = __webpack_require__(17);
module.exports = function(target, src, safe){
for(var key in src){
if(safe && target[key])target[key] = src[key];
else hide(target, key, src[key]);
} return target;
};
/***/ }),
/* 66 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var global = __webpack_require__(13)
, core = __webpack_require__(14)
, dP = __webpack_require__(18)
, DESCRIPTORS = __webpack_require__(22)
, SPECIES = __webpack_require__(47)('species');
module.exports = function(KEY){
var C = typeof core[KEY] == 'function' ? core[KEY] : global[KEY];
if(DESCRIPTORS && C && !C[SPECIES])dP.f(C, SPECIES, {
configurable: true,
get: function(){ return this; }
});
};
/***/ }),
/* 67 */
/***/ (function(module, exports, __webpack_require__) {
var ITERATOR = __webpack_require__(47)('iterator')
, SAFE_CLOSING = false;
try {
var riter = [7][ITERATOR]();
riter['return'] = function(){ SAFE_CLOSING = true; };
Array.from(riter, function(){ throw 2; });
} catch(e){ /* empty */ }
module.exports = function(exec, skipClosing){
if(!skipClosing && !SAFE_CLOSING)return false;
var safe = false;
try {
var arr = [7]
, iter = arr[ITERATOR]();
iter.next = function(){ return {done: safe = true}; };
arr[ITERATOR] = function(){ return iter; };
exec(arr);
} catch(e){ /* empty */ }
return safe;
};
/***/ }),
/* 68 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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; }; }(); /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Invoker - invoke commands
*/
var _tuiCodeSnippet = __webpack_require__(3);
var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var eventNames = _consts2.default.eventNames,
rejectMessages = _consts2.default.rejectMessages;
var isFunction = _tuiCodeSnippet2.default.isFunction,
isString = _tuiCodeSnippet2.default.isString,
CustomEvents = _tuiCodeSnippet2.default.CustomEvents;
/**
* Invoker
* @class
* @ignore
*/
var Invoker = function () {
function Invoker() {
_classCallCheck(this, Invoker);
/**
* Undo stack
* @type {Array.<Command>}
* @private
*/
this._undoStack = [];
/**
* Redo stack
* @type {Array.<Command>}
* @private
*/
this._redoStack = [];
/**
* Lock-flag for executing command
* @type {boolean}
* @private
*/
this._isLocked = false;
}
/**
* Invoke command execution
* @param {Command} command - Command
* @returns {Promise}
* @private
*/
_createClass(Invoker, [{
key: '_invokeExecution',
value: function _invokeExecution(command) {
var _this = this;
this.lock();
var args = command.args;
if (!args) {
args = [];
}
return command.execute.apply(command, args).then(function (value) {
_this.pushUndoStack(command);
_this.unlock();
if (isFunction(command.executeCallback)) {
command.executeCallback(value);
}
return value;
})['catch'](function (message) {
_this.unlock();
return _promise2.default.reject(message);
});
}
/**
* Invoke command undo
* @param {Command} command - Command
* @returns {Promise}
* @private
*/
}, {
key: '_invokeUndo',
value: function _invokeUndo(command) {
var _this2 = this;
this.lock();
var args = command.args;
if (!args) {
args = [];
}
return command.undo.apply(command, args).then(function (value) {
_this2.pushRedoStack(command);
_this2.unlock();
if (isFunction(command.undoCallback)) {
command.undoCallback(value);
}
return value;
})['catch'](function (message) {
_this2.unlock();
return _promise2.default.reject(message);
});
}
/**
* fire REDO_STACK_CHANGED event
* @private
*/
}, {
key: '_fireRedoStackChanged',
value: function _fireRedoStackChanged() {
this.fire(eventNames.REDO_STACK_CHANGED, this._redoStack.length);
}
/**
* fire UNDO_STACK_CHANGED event
* @private
*/
}, {
key: '_fireUndoStackChanged',
value: function _fireUndoStackChanged() {
this.fire(eventNames.UNDO_STACK_CHANGED, this._undoStack.length);
}
/**
* Lock this invoker
*/
}, {
key: 'lock',
value: function lock() {
this._isLocked = true;
}
/**
* Unlock this invoker
*/
}, {
key: 'unlock',
value: function unlock() {
this._isLocked = false;
}
/**
* Invoke command
* Store the command to the undoStack
* Clear the redoStack
* @param {String} commandName - Command name
* @param {...*} args - Arguments for creating command
* @returns {Promise}
*/
}, {
key: 'execute',
value: function execute() {
var _this3 = this;
if (this._isLocked) {
return _promise2.default.reject(rejectMessages.isLock);
}
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var command = args[0];
if (isString(command)) {
command = _command2.default.create.apply(_command2.default, args);
}
return this._invokeExecution(command).then(function (value) {
_this3.clearRedoStack();
return value;
});
}
/**
* Undo command
* @returns {Promise}
*/
}, {
key: 'undo',
value: function undo() {
var command = this._undoStack.pop();
var promise = void 0;
var message = '';
if (command && this._isLocked) {
this.pushUndoStack(command, true);
command = null;
}
if (command) {
if (this.isEmptyUndoStack()) {
this._fireUndoStackChanged();
}
promise = this._invokeUndo(command);
} else {
message = rejectMessages.undo;
if (this._isLocked) {
message = message + ' Because ' + rejectMessages.isLock;
}
promise = _promise2.default.reject(message);
}
return promise;
}
/**
* Redo command
* @returns {Promise}
*/
}, {
key: 'redo',
value: function redo() {
var command = this._redoStack.pop();
var promise = void 0;
var message = '';
if (command && this._isLocked) {
this.pushRedoStack(command, true);
command = null;
}
if (command) {
if (this.isEmptyRedoStack()) {
this._fireRedoStackChanged();
}
promise = this._invokeExecution(command);
} else {
message = rejectMessages.redo;
if (this._isLocked) {
message = message + ' Because ' + rejectMessages.isLock;
}
promise = _promise2.default.reject(message);
}
return promise;
}
/**
* Push undo stack
* @param {Command} command - command
* @param {boolean} [isSilent] - Fire event or not
*/
}, {
key: 'pushUndoStack',
value: function pushUndoStack(command, isSilent) {
this._undoStack.push(command);
if (!isSilent) {
this._fireUndoStackChanged();
}
}
/**
* Push redo stack
* @param {Command} command - command
* @param {boolean} [isSilent] - Fire event or not
*/
}, {
key: 'pushRedoStack',
value: function pushRedoStack(command, isSilent) {
this._redoStack.push(command);
if (!isSilent) {
this._fireRedoStackChanged();
}
}
/**
* Return whether the redoStack is empty
* @returns {boolean}
*/
}, {
key: 'isEmptyRedoStack',
value: function isEmptyRedoStack() {
return this._redoStack.length === 0;
}
/**
* Return whether the undoStack is empty
* @returns {boolean}
*/
}, {
key: 'isEmptyUndoStack',
value: function isEmptyUndoStack() {
return this._undoStack.length === 0;
}
/**
* Clear undoStack
*/
}, {
key: 'clearUndoStack',
value: function clearUndoStack() {
if (!this.isEmptyUndoStack()) {
this._undoStack = [];
this._fireUndoStackChanged();
}
}
/**
* Clear redoStack
*/
}, {
key: 'clearRedoStack',
value: function clearRedoStack() {
if (!this.isEmptyRedoStack()) {
this._redoStack = [];
this._fireRedoStackChanged();
}
}
}]);
return Invoker;
}();
CustomEvents.mixin(Invoker);
module.exports = Invoker;
/***/ }),
/* 69 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(70);
var _command2 = _interopRequireDefault(_command);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var commands = {};
/**
* Create a command
* @param {string} name - Command name
* @param {...*} args - Arguments for creating command
* @returns {Command}
* @ignore
*/
/**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Command factory
*/
function create(name) {
var actions = commands[name];
if (actions) {
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
return new _command2.default(actions, args);
}
return null;
}
/**
* Register a command with name as a key
* @param {Object} command - {name:{string}, execute: {function}, undo: {function}}
* @param {string} command.name - command name
* @param {function} command.execute - executable function
* @param {function} command.undo - undo function
* @ignore
*/
function register(command) {
commands[command.name] = command;
}
module.exports = {
create: create,
register: register
};
/***/ }),
/* 70 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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; }; }(); /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Command interface
*/
var _errorMessage = __webpack_require__(71);
var _errorMessage2 = _interopRequireDefault(_errorMessage);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var createMessage = _errorMessage2.default.create;
var errorTypes = _errorMessage2.default.types;
/**
* Command class
* @class
* @param {{name:function, execute: function, undo: function,
* executeCallback: function, undoCallback: function}} actions - Command actions
* @param {Array} args - passing arguments on execute, undo
* @ignore
*/
var Command = function () {
function Command(actions, args) {
_classCallCheck(this, Command);
/**
* command name
* @type {string}
*/
this.name = actions.name;
/**
* arguments
* @type {Array}
*/
this.args = args;
/**
* Execute function
* @type {function}
*/
this.execute = actions.execute;
/**
* Undo function
* @type {function}
*/
this.undo = actions.undo;
/**
* executeCallback
* @type {function}
*/
this.executeCallback = actions.executeCallback || null;
/**
* undoCallback
* @type {function}
*/
this.undoCallback = actions.undoCallback || null;
/**
* data for undo
* @type {Object}
*/
this.undoData = {};
}
/**
* Execute action
* @param {Object.<string, Component>} compMap - Components injection
* @abstract
*/
_createClass(Command, [{
key: 'execute',
value: function execute() {
throw new Error(createMessage(errorTypes.UN_IMPLEMENTATION, 'execute'));
}
/**
* Undo action
* @param {Object.<string, Component>} compMap - Components injection
* @abstract
*/
}, {
key: 'undo',
value: function undo() {
throw new Error(createMessage(errorTypes.UN_IMPLEMENTATION, 'undo'));
}
/**
* Attach execute callabck
* @param {function} callback - Callback after execution
* @returns {Command} this
*/
}, {
key: 'setExecuteCallback',
value: function setExecuteCallback(callback) {
this.executeCallback = callback;
return this;
}
/**
* Attach undo callback
* @param {function} callback - Callback after undo
* @returns {Command} this
*/
}, {
key: 'setUndoCallback',
value: function setUndoCallback(callback) {
this.undoCallback = callback;
return this;
}
}]);
return Command;
}();
module.exports = Command;
/***/ }),
/* 71 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _tuiCodeSnippet = __webpack_require__(3);
var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet);
var _util = __webpack_require__(72);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Error-message factory
*/
var types = (0, _util.keyMirror)('UN_IMPLEMENTATION', 'NO_COMPONENT_NAME');
var messages = {
UN_IMPLEMENTATION: 'Should implement a method: ',
NO_COMPONENT_NAME: 'Should set a component name'
};
var map = {
UN_IMPLEMENTATION: function UN_IMPLEMENTATION(methodName) {
return messages.UN_IMPLEMENTATION + methodName;
},
NO_COMPONENT_NAME: function NO_COMPONENT_NAME() {
return messages.NO_COMPONENT_NAME;
}
};
module.exports = {
types: _tuiCodeSnippet2.default.extend({}, types),
create: function create(type) {
type = type.toLowerCase();
var func = map[type];
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
return func.apply(undefined, args);
}
};
/***/ }),
/* 72 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _tuiCodeSnippet = __webpack_require__(3);
// import {imagePing} from 'tui-code-snippet';
var min = Math.min,
max = Math.max;
// let hostnameSent = false;
/**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Util
*/
module.exports = {
/**
* Clamp value
* @param {number} value - Value
* @param {number} minValue - Minimum value
* @param {number} maxValue - Maximum value
* @returns {number} clamped value
*/
clamp: function clamp(value, minValue, maxValue) {
var temp = void 0;
if (minValue > maxValue) {
temp = minValue;
minValue = maxValue;
maxValue = temp;
}
return max(minValue, min(value, maxValue));
},
/**
* Make key-value object from arguments
* @returns {object.<string, string>}
*/
keyMirror: function keyMirror() {
var obj = {};
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
(0, _tuiCodeSnippet.forEach)(args, function (key) {
obj[key] = key;
});
return obj;
},
/**
* Make CSSText
* @param {Object} styleObj - Style info object
* @returns {string} Connected string of style
*/
makeStyleText: function makeStyleText(styleObj) {
var styleStr = '';
(0, _tuiCodeSnippet.forEach)(styleObj, function (value, prop) {
styleStr += prop + ': ' + value + ';';
});
return styleStr;
},
/**
* Get object's properties
* @param {Object} obj - object
* @param {Array} keys - keys
* @returns {Object} properties object
*/
getProperties: function getProperties(obj, keys) {
var props = {};
var length = keys.length;
var i = 0;
var key = void 0;
for (i = 0; i < length; i += 1) {
key = keys[i];
props[key] = obj[key];
}
return props;
},
/**
* ParseInt simpliment
* @param {number} value - Value
* @returns {number}
*/
toInteger: function toInteger(value) {
return parseInt(value, 10);
},
/**
* String to camelcase string
* @param {string} targetString - change target
* @returns {string}
* @private
*/
toCamelCase: function toCamelCase(targetString) {
return targetString.replace(/-([a-z])/g, function ($0, $1) {
return $1.toUpperCase();
});
},
/**
* Check browser file api support
* @returns {boolean}
* @private
*/
isSupportFileApi: function isSupportFileApi() {
return !!(window.File && window.FileList && window.FileReader);
},
/**
* hex to rgb
* @param {string} color - hex color
* @param {string} alpha - color alpha value
* @returns {string} rgb expression
*/
getRgb: function getRgb(color, alpha) {
if (color.length === 4) {
color = '' + color + color.slice(1, 4);
}
var r = parseInt(color.slice(1, 3), 16);
var g = parseInt(color.slice(3, 5), 16);
var b = parseInt(color.slice(5, 7), 16);
var a = alpha || 1;
return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + a + ')';
},
/**
* send hostname
* @returns {null}
*/
sendHostName: function sendHostName() {
return null;
/*
const {hostname} = location;
if (hostnameSent) {
return;
}
hostnameSent = true;
imagePing('https://www.google-analytics.com/collect', {
v: 1,
t: 'event',
tid: 'UA-115377265-9',
cid: hostname,
dp: hostname,
dh: 'image-editor'
});
*/
},
/**
* Apply css resource
* @param {string} styleBuffer - serialized css text
* @param {string} tagId - style tag id
*/
styleLoad: function styleLoad(styleBuffer, tagId) {
var _document$getElements = document.getElementsByTagName('head'),
head = _document$getElements[0];
var linkElement = document.createElement('link');
var styleData = encodeURIComponent(styleBuffer);
if (tagId) {
linkElement.id = tagId;
// linkElement.id = 'tui-image-editor-theme-style';
}
linkElement.setAttribute('rel', 'stylesheet');
linkElement.setAttribute('type', 'text/css');
linkElement.setAttribute('href', 'data:text/css;charset=UTF-8,' + styleData);
head.appendChild(linkElement);
},
/**
* Get selector
* @param {HTMLElement} targetElement - target element
* @returns {Function} selector
*/
getSelector: function getSelector(targetElement) {
return function (str) {
return targetElement.querySelector(str);
};
},
/**
* Change base64 to blob
* @param {String} data - base64 string data
* @returns {Blob} Blob Data
*/
base64ToBlob: function base64ToBlob(data) {
var rImageType = /data:(image\/.+);base64,/;
var mimeString = '';
var raw = void 0,
uInt8Array = void 0,
i = void 0;
raw = data.replace(rImageType, function (header, imageType) {
mimeString = imageType;
return '';
});
raw = atob(raw);
var rawLength = raw.length;
uInt8Array = new Uint8Array(rawLength); // eslint-disable-line
for (i = 0; i < rawLength; i += 1) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], { type: mimeString });
}
};
/***/ }),
/* 73 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _util = __webpack_require__(72);
var _util2 = _interopRequireDefault(_util);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
module.exports = {
/**
* Component names
* @type {Object.<string, string>}
*/
componentNames: _util2.default.keyMirror('IMAGE_LOADER', 'CROPPER', 'FLIP', 'ROTATION', 'FREE_DRAWING', 'LINE', 'TEXT', 'ICON', 'FILTER', 'SHAPE'),
/**
* Command names
* @type {Object.<string, string>}
*/
commandNames: {
'CLEAR_OBJECTS': 'clearObjects',
'LOAD_IMAGE': 'loadImage',
'FLIP_IMAGE': 'flip',
'ROTATE_IMAGE': 'rotate',
'ADD_OBJECT': 'addObject',
'REMOVE_OBJECT': 'removeObject',
'APPLY_FILTER': 'applyFilter',
'REMOVE_FILTER': 'removeFilter',
'ADD_ICON': 'addIcon',
'CHANGE_ICON_COLOR': 'changeIconColor',
'ADD_SHAPE': 'addShape',
'CHANGE_SHAPE': 'changeShape',
'ADD_TEXT': 'addText',
'ADD_TEXTS': 'addTexts',
'CHANGE_TEXT': 'changeText',
'CHANGE_TEXT_STYLE': 'changeTextStyle',
'ADD_IMAGE_OBJECT': 'addImageObject',
'RESIZE_CANVAS_DIMENSION': 'resizeCanvasDimension',
'SET_OBJECT_PROPERTIES': 'setObjectProperties',
'SET_OBJECT_POSITION': 'setObjectPosition',
'SET_OBJECT_POSITIONS': 'setObjectPositions'
},
/**
* Event names
* @type {Object.<string, string>}
*/
eventNames: {
OBJECT_ACTIVATED: 'objectActivated',
OBJECT_MOVED: 'objectMoved',
OBJECT_SCALED: 'objectScaled',
OBJECT_CREATED: 'objectCreated',
OBJECT_ROTATE_FIX: 'objectRotateFix',
OBJECT_REMOVE: 'objectRemove',
TEXT_EDITING: 'textEditing',
TEXT_CHANGED: 'textChanged',
ICON_CREATE_RESIZE: 'iconCreateResize',
ICON_CREATE_END: 'iconCreateEnd',
ADD_TEXT: 'addText',
ADD_OBJECT: 'addObject',
ADD_OBJECT_AFTER: 'addObjectAfter',
MOUSE_DOWN: 'mousedown',
MOUSE_UP: 'mouseup',
MOUSE_MOVE: 'mousemove',
// UNDO/REDO Events
REDO_STACK_CHANGED: 'redoStackChanged',
UNDO_STACK_CHANGED: 'undoStackChanged',
SELECTION_CLEARED: 'selectionCleared',
SELECTION_CREATED: 'selectionCreated'
},
/**
* Editor states
* @type {Object.<string, string>}
*/
drawingModes: _util2.default.keyMirror('NORMAL', 'CROPPER', 'FREE_DRAWING', 'LINE_DRAWING', 'TEXT', 'SHAPE'),
/**
* Shortcut key values
* @type {Object.<string, number>}
*/
keyCodes: {
Z: 90,
Y: 89,
SHIFT: 16,
BACKSPACE: 8,
DEL: 46
},
/**
* Fabric object options
* @type {Object.<string, Object>}
*/
fObjectOptions: {
SELECTION_STYLE: {
borderColor: '#fff',
cornerColor: 'yellow',
cornerStyle: 'editor',
hasRotatingPoint: false,
originX: 'center',
originY: 'center',
transparentCorners: false
}
},
/**
* Promise reject messages
* @type {Object.<string, string>}
*/
rejectMessages: {
flip: 'The flipX and flipY setting values are not changed.',
rotation: 'The current angle is same the old angle.',
loadImage: 'The background image is empty.',
isLock: 'The executing command state is locked.',
undo: 'The promise of undo command is reject.',
redo: 'The promise of redo command is reject.',
invalidDrawingMode: 'This operation is not supported in the drawing mode',
invalidParameters: 'Invalid parameters',
noActiveObject: 'There is no active object.',
unsupportedType: 'Unsupported object type',
noObject: 'The object is not in canvas.',
addedObject: 'The object is already added.'
},
/**
* Default icon menu svg path
* @type {Object.<string, string>}
*/
defaultIconPath: {
'icon-arrow': 'M40 12V0l24 24-24 24V36H0V12h40z',
'icon-arrow-2': 'M49,32 H3 V22 h46 l-18,-18 h12 l23,23 L43,50 h-12 l18,-18 z ',
'icon-arrow-3': 'M43.349998,27 L17.354,53 H1.949999 l25.996,-26 L1.949999,1 h15.404 L43.349998,27 z ',
'icon-star': 'M35,54.557999 l-19.912001,10.468 l3.804,-22.172001 l-16.108,-15.7 l22.26,-3.236 L35,3.746 l9.956,20.172001 l22.26,3.236 l-16.108,15.7 l3.804,22.172001 z ',
'icon-star-2': 'M17,31.212 l-7.194,4.08 l-4.728,-6.83 l-8.234,0.524 l-1.328,-8.226 l-7.644,-3.14 l2.338,-7.992 l-5.54,-6.18 l5.54,-6.176 l-2.338,-7.994 l7.644,-3.138 l1.328,-8.226 l8.234,0.522 l4.728,-6.83 L17,-24.312 l7.194,-4.08 l4.728,6.83 l8.234,-0.522 l1.328,8.226 l7.644,3.14 l-2.338,7.992 l5.54,6.178 l-5.54,6.178 l2.338,7.992 l-7.644,3.14 l-1.328,8.226 l-8.234,-0.524 l-4.728,6.83 z ',
'icon-polygon': 'M3,31 L19,3 h32 l16,28 l-16,28 H19 z ',
'icon-location': 'M24 62C8 45.503 0 32.837 0 24 0 10.745 10.745 0 24 0s24 10.745 24 24c0 8.837-8 21.503-24 38zm0-28c5.523 0 10-4.477 10-10s-4.477-10-10-10-10 4.477-10 10 4.477 10 10 10z',
'icon-heart': 'M49.994999,91.349998 l-6.96,-6.333 C18.324001,62.606995 2.01,47.829002 2.01,29.690998 C2.01,14.912998 13.619999,3.299999 28.401001,3.299999 c8.349,0 16.362,5.859 21.594,12 c5.229,-6.141 13.242001,-12 21.591,-12 c14.778,0 26.390999,11.61 26.390999,26.390999 c0,18.138 -16.314001,32.916 -41.025002,55.374001 l-6.96,6.285 z ',
'icon-bubble': 'M44 48L34 58V48H12C5.373 48 0 42.627 0 36V12C0 5.373 5.373 0 12 0h40c6.627 0 12 5.373 12 12v24c0 6.627-5.373 12-12 12h-8z'
},
defaultRotateRangeValus: {
realTimeEvent: true,
min: -360,
max: 360,
value: 0
},
defaultDrawRangeValus: {
min: 5,
max: 30,
value: 12
},
defaultShapeStrokeValus: {
realTimeEvent: false,
min: 2,
max: 300,
value: 3
},
defaultTextRangeValus: {
realTimeEvent: true,
min: 10,
max: 100,
value: 50
},
defaultFilterRangeValus: {
tintOpacityRange: {
min: 0,
max: 1,
value: 0.7
},
removewhiteThresholdRange: {
min: 0,
max: 255,
value: 60
},
removewhiteDistanceRange: {
min: 0,
max: 255,
value: 10
},
gradientTransparencyRange: {
min: 0,
max: 255,
value: 100
},
brightnessRange: {
min: -255,
max: 255,
value: 100
},
noiseRange: {
min: 0,
max: 1000,
value: 100
},
pixelateRange: {
min: 2,
max: 20,
value: 4
},
colorfilterThresholeRange: {
min: 0,
max: 255,
value: 45
}
}
}; /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Constants
*/
/***/ }),
/* 74 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _tuiCodeSnippet = __webpack_require__(3);
var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet);
var _util = __webpack_require__(72);
var _util2 = _interopRequireDefault(_util);
var _mainContainer = __webpack_require__(75);
var _mainContainer2 = _interopRequireDefault(_mainContainer);
var _controls = __webpack_require__(76);
var _controls2 = _interopRequireDefault(_controls);
var _theme = __webpack_require__(77);
var _theme2 = _interopRequireDefault(_theme);
var _shape = __webpack_require__(80);
var _shape2 = _interopRequireDefault(_shape);
var _crop = __webpack_require__(86);
var _crop2 = _interopRequireDefault(_crop);
var _flip = __webpack_require__(88);
var _flip2 = _interopRequireDefault(_flip);
var _rotate = __webpack_require__(90);
var _rotate2 = _interopRequireDefault(_rotate);
var _text = __webpack_require__(92);
var _text2 = _interopRequireDefault(_text);
var _mask = __webpack_require__(94);
var _mask2 = _interopRequireDefault(_mask);
var _icon = __webpack_require__(96);
var _icon2 = _interopRequireDefault(_icon);
var _draw = __webpack_require__(98);
var _draw2 = _interopRequireDefault(_draw);
var _filter = __webpack_require__(100);
var _filter2 = _interopRequireDefault(_filter);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var SUB_UI_COMPONENT = {
Shape: _shape2.default,
Crop: _crop2.default,
Flip: _flip2.default,
Rotate: _rotate2.default,
Text: _text2.default,
Mask: _mask2.default,
Icon: _icon2.default,
Draw: _draw2.default,
Filter: _filter2.default
};
var BI_EXPRESSION_MINSIZE_WHEN_TOP_POSITION = '1300';
/**
* Ui class
* @class
* @param {string|jQuery|HTMLElement} element - Wrapper's element or selector
* @param {Object} [options] - Ui setting options
* @param {number} option.loadImage - Init default load image
* @param {number} option.initMenu - Init start menu
* @param {Boolean} [option.menuBarPosition=bottom] - Let
* @param {Boolean} [option.applyCropSelectionStyle=false] - Let
* @param {Objecdt} actions - ui action instance
* @ignore
*/
var Ui = function () {
function Ui(element, options, actions) {
_classCallCheck(this, Ui);
this.options = this._initializeOption(options);
this._actions = actions;
this.submenu = false;
this.imageSize = {};
this.uiSize = {};
this.theme = new _theme2.default(this.options.theme);
this._submenuChangeTransection = false;
this._selectedElement = null;
this._mainElement = null;
this._editorElementWrap = null;
this._editorElement = null;
this._menuElement = null;
this._subMenuElement = null;
this._makeUiElement(element);
this._setUiSize();
this._els = {
'undo': this._menuElement.querySelector('#tie-btn-undo'),
'redo': this._menuElement.querySelector('#tie-btn-redo'),
'reset': this._menuElement.querySelector('#tie-btn-reset'),
'delete': this._menuElement.querySelector('#tie-btn-delete'),
'deleteAll': this._menuElement.querySelector('#tie-btn-delete-all'),
'download': this._selectedElement.querySelectorAll('.tui-image-editor-download-btn'),
'load': this._selectedElement.querySelectorAll('.tui-image-editor-load-btn')
};
this._makeSubMenu();
}
/**
* Set Default Selection for includeUI
* @param {Object} option - imageEditor options
* @returns {Object} - extends selectionStyle option
*/
_createClass(Ui, [{
key: 'setUiDefaultSelectionStyle',
value: function setUiDefaultSelectionStyle(option) {
return _tuiCodeSnippet2.default.extend({
applyCropSelectionStyle: true,
applyGroupSelectionStyle: true,
selectionStyle: {
cornerStyle: 'circle',
cornerSize: 16,
cornerColor: '#fff',
cornerStrokeColor: '#fff',
transparentCorners: false,
lineWidth: 2,
borderColor: '#fff'
}
}, option);
}
/**
* Change editor size
* @param {Object} resizeInfo - ui & image size info
* @param {Object} resizeInfo.uiSize - image size dimension
* @param {Number} resizeInfo.uiSize.width - ui width
* @param {Number} resizeInfo.uiSize.height - ui height
* @param {Object} resizeInfo.imageSize - image size dimension
* @param {Number} resizeInfo.imageSize.oldWidth - old width
* @param {Number} resizeInfo.imageSize.oldHeight - old height
* @param {Number} resizeInfo.imageSize.newWidth - new width
* @param {Number} resizeInfo.imageSize.newHeight - new height
*/
}, {
key: 'resizeEditor',
value: function resizeEditor() {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
uiSize = _ref.uiSize,
_ref$imageSize = _ref.imageSize,
imageSize = _ref$imageSize === undefined ? this.imageSize : _ref$imageSize;
if (imageSize !== this.imageSize) {
this.imageSize = imageSize;
}
if (uiSize) {
this._setUiSize(uiSize);
}
var _getEditorDimension2 = this._getEditorDimension(),
width = _getEditorDimension2.width,
height = _getEditorDimension2.height;
var editorElementStyle = this._editorElement.style;
var menuBarPosition = this.options.menuBarPosition;
editorElementStyle.height = height + 'px';
editorElementStyle.width = width + 'px';
this._setEditorPosition(menuBarPosition);
this._editorElementWrap.style.bottom = '0px';
this._editorElementWrap.style.top = '0px';
this._editorElementWrap.style.left = '0px';
this._editorElementWrap.style.width = '100%';
var selectElementClassList = this._selectedElement.classList;
if (menuBarPosition === 'top' && this._selectedElement.offsetWidth < BI_EXPRESSION_MINSIZE_WHEN_TOP_POSITION) {
selectElementClassList.add('tui-image-editor-top-optimization');
} else {
selectElementClassList.remove('tui-image-editor-top-optimization');
}
}
/**
* Change undo button status
* @param {Boolean} enableStatus - enabled status
*/
}, {
key: 'changeUndoButtonStatus',
value: function changeUndoButtonStatus(enableStatus) {
if (enableStatus) {
this._els.undo.classList.add('enabled');
} else {
this._els.undo.classList.remove('enabled');
}
}
/**
* Change redo button status
* @param {Boolean} enableStatus - enabled status
*/
}, {
key: 'changeRedoButtonStatus',
value: function changeRedoButtonStatus(enableStatus) {
if (enableStatus) {
this._els.redo.classList.add('enabled');
} else {
this._els.redo.classList.remove('enabled');
}
}
/**
* Change reset button status
* @param {Boolean} enableStatus - enabled status
*/
}, {
key: 'changeResetButtonStatus',
value: function changeResetButtonStatus(enableStatus) {
if (enableStatus) {
this._els.reset.classList.add('enabled');
} else {
this._els.reset.classList.remove('enabled');
}
}
/**
* Change delete-all button status
* @param {Boolean} enableStatus - enabled status
*/
}, {
key: 'changeDeleteAllButtonEnabled',
value: function changeDeleteAllButtonEnabled(enableStatus) {
if (enableStatus) {
this._els.deleteAll.classList.add('enabled');
} else {
this._els.deleteAll.classList.remove('enabled');
}
}
/**
* Change delete button status
* @param {Boolean} enableStatus - enabled status
*/
}, {
key: 'changeDeleteButtonEnabled',
value: function changeDeleteButtonEnabled(enableStatus) {
if (enableStatus) {
this._els['delete'].classList.add('enabled');
} else {
this._els['delete'].classList.remove('enabled');
}
}
/**
* Change delete button status
* @param {Object} [options] - Ui setting options
* @param {number} option.loadImage - Init default load image
* @param {number} option.initMenu - Init start menu
* @param {Boolean} [option.menuBarPosition=bottom] - Let
* @param {Boolean} [option.applyCropSelectionStyle=false] - Let
* @returns {Object} initialize option
* @private
*/
}, {
key: '_initializeOption',
value: function _initializeOption(options) {
return _tuiCodeSnippet2.default.extend({
loadImage: {
path: '',
name: ''
},
menuIconPath: '',
menu: ['crop', 'flip', 'rotate', 'draw', 'shape', 'icon', 'text', 'mask', 'filter'],
initMenu: false,
uiSize: {
width: '100%',
height: '100%'
},
menuBarPosition: 'bottom'
}, options);
}
/**
* Set ui container size
* @param {Object} uiSize - ui dimension
* @param {number} width - width
* @param {number} height - height
* @private
*/
}, {
key: '_setUiSize',
value: function _setUiSize() {
var uiSize = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.options.uiSize;
var elementDimension = this._selectedElement.style;
elementDimension.width = uiSize.width;
elementDimension.height = uiSize.height;
}
/**
* Make submenu dom element
* @private
*/
}, {
key: '_makeSubMenu',
value: function _makeSubMenu() {
var _this = this;
_tuiCodeSnippet2.default.forEach(this.options.menu, function (menuName) {
var SubComponentClass = SUB_UI_COMPONENT[menuName.replace(/^[a-z]/, function ($0) {
return $0.toUpperCase();
})];
// make menu element
_this._makeMenuElement(menuName);
// menu btn element
_this._els[menuName] = _this._menuElement.querySelector('#tie-btn-' + menuName);
// submenu ui instance
_this[menuName] = new SubComponentClass(_this._subMenuElement, {
iconStyle: _this.theme.getStyle('submenu.icon'),
menuBarPosition: _this.options.menuBarPosition
});
});
}
/**
* Make primary ui dom element
* @param {string|jQuery|HTMLElement} element - Wrapper's element or selector
* @private
*/
}, {
key: '_makeUiElement',
value: function _makeUiElement(element) {
var selectedElement = void 0;
window.snippet = _tuiCodeSnippet2.default;
if (element.jquery) {
selectedElement = element[0];
} else if (element.nodeType) {
selectedElement = element;
} else {
selectedElement = document.querySelector(element);
}
var selector = _util2.default.getSelector(selectedElement);
selectedElement.classList.add('tui-image-editor-container');
selectedElement.innerHTML = (0, _controls2.default)({
biImage: this.theme.getStyle('common.bi'),
iconStyle: this.theme.getStyle('menu.icon'),
loadButtonStyle: this.theme.getStyle('loadButton'),
downloadButtonStyle: this.theme.getStyle('downloadButton')
}) + (0, _mainContainer2.default)({
biImage: this.theme.getStyle('common.bi'),
commonStyle: this.theme.getStyle('common'),
headerStyle: this.theme.getStyle('header'),
loadButtonStyle: this.theme.getStyle('loadButton'),
downloadButtonStyle: this.theme.getStyle('downloadButton'),
submenuStyle: this.theme.getStyle('submenu')
});
this._selectedElement = selectedElement;
this._selectedElement.classList.add(this.options.menuBarPosition);
this._mainElement = selector('.tui-image-editor-main');
this._editorElementWrap = selector('.tui-image-editor-wrap');
this._editorElement = selector('.tui-image-editor');
this._menuElement = selector('.tui-image-editor-menu');
this._subMenuElement = selector('.tui-image-editor-submenu');
}
/**
* Make menu ui dom element
* @param {string} menuName - menu name
* @private
*/
}, {
key: '_makeMenuElement',
value: function _makeMenuElement(menuName) {
var btnElement = document.createElement('li');
var _theme$getStyle = this.theme.getStyle('menu.icon'),
normal = _theme$getStyle.normal,
active = _theme$getStyle.active,
hover = _theme$getStyle.hover;
var menuItemHtml = '\n <svg class="svg_ic-menu">\n <use xlink:href="' + normal.path + '#' + normal.name + '-ic-' + menuName + '" class="normal"/>\n <use xlink:href="' + active.path + '#' + active.name + '-ic-' + menuName + '" class="active"/>\n <use xlink:href="' + hover.path + '#' + hover.name + '-ic-' + menuName + '" class="hover"/>\n </svg>\n ';
btnElement.id = 'tie-btn-' + menuName;
btnElement.className = 'tui-image-editor-item normal';
btnElement.title = menuName.replace(/^[a-z]/g, function ($0) {
return $0.toUpperCase();
});
btnElement.innerHTML = menuItemHtml;
this._menuElement.appendChild(btnElement);
}
/**
* Add help action event
* @param {string} helpName - help menu name
* @private
*/
}, {
key: '_addHelpActionEvent',
value: function _addHelpActionEvent(helpName) {
var _this2 = this;
this._els[helpName].addEventListener('click', function () {
_this2._actions.main[helpName]();
});
}
/**
* Add download event
* @private
*/
}, {
key: '_addDownloadEvent',
value: function _addDownloadEvent() {
var _this3 = this;
_tuiCodeSnippet2.default.forEach(this._els.download, function (element) {
element.addEventListener('click', function () {
_this3._actions.main.download();
});
});
}
/**
* Add load event
* @private
*/
}, {
key: '_addLoadEvent',
value: function _addLoadEvent() {
var _this4 = this;
_tuiCodeSnippet2.default.forEach(this._els.load, function (element) {
element.addEventListener('change', function (event) {
_this4._actions.main.load(event.target.files[0]);
});
});
}
/**
* Add menu event
* @param {string} menuName - menu name
* @private
*/
}, {
key: '_addMenuEvent',
value: function _addMenuEvent(menuName) {
var _this5 = this;
this._els[menuName].addEventListener('click', function () {
_this5.changeMenu(menuName);
});
}
/**
* Add menu event
* @param {string} menuName - menu name
* @private
*/
}, {
key: '_addSubMenuEvent',
value: function _addSubMenuEvent(menuName) {
this[menuName].addEvent(this._actions[menuName]);
}
/**
* get editor area element
* @returns {HTMLElement} editor area html element
*/
}, {
key: 'getEditorArea',
value: function getEditorArea() {
return this._editorElement;
}
/**
* Init canvas
*/
}, {
key: 'initCanvas',
value: function initCanvas() {
var _this6 = this;
var loadImageInfo = this._getLoadImage();
if (loadImageInfo) {
this._actions.main.initLoadImage(loadImageInfo.path, loadImageInfo.name).then(function () {
_this6._addHelpActionEvent('undo');
_this6._addHelpActionEvent('redo');
_this6._addHelpActionEvent('reset');
_this6._addHelpActionEvent('delete');
_this6._addHelpActionEvent('deleteAll');
_this6._addDownloadEvent();
_this6._addLoadEvent();
_tuiCodeSnippet2.default.forEach(_this6.options.menu, function (menuName) {
_this6._addMenuEvent(menuName);
_this6._addSubMenuEvent(menuName);
});
_this6._initMenu();
});
}
var gridVisual = document.createElement('div');
gridVisual.className = 'tui-image-editor-grid-visual';
var grid = '<table>\n <tr><td class="dot left-top"></td><td></td><td class="dot right-top"></td></tr>\n <tr><td></td><td></td><td></td></tr>\n <tr><td class="dot left-bottom"></td><td></td><td class="dot right-bottom"></td></tr>\n </table>';
gridVisual.innerHTML = grid;
this._editorContainerElement = this._editorElement.querySelector('.tui-image-editor-canvas-container');
this._editorContainerElement.appendChild(gridVisual);
}
/**
* get editor area element
* @returns {Object} loadimage optionk
* @private
*/
}, {
key: '_getLoadImage',
value: function _getLoadImage() {
return this.options.loadImage;
}
/**
* change menu
* @param {string} menuName - menu name
* @param {boolean} toggle - whether toogle or not
* @param {boolean} discardSelection - discard selection
*/
}, {
key: 'changeMenu',
value: function changeMenu(menuName) {
var toggle = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var discardSelection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
if (!this._submenuChangeTransection) {
this._submenuChangeTransection = true;
this._changeMenu(menuName, toggle, discardSelection);
this._submenuChangeTransection = false;
}
}
/**
* change menu
* @param {string} menuName - menu name
* @param {boolean} toggle - whether toogle or not
* @param {boolean} discardSelection - discard selection
* @private
*/
}, {
key: '_changeMenu',
value: function _changeMenu(menuName, toggle, discardSelection) {
if (this.submenu) {
this._els[this.submenu].classList.remove('active');
this._mainElement.classList.remove('tui-image-editor-menu-' + this.submenu);
if (discardSelection) {
this._actions.main.discardSelection();
}
this._actions.main.changeSelectableAll(true);
this[this.submenu].changeStandbyMode();
}
if (this.submenu === menuName && toggle) {
this.submenu = null;
} else {
this._els[menuName].classList.add('active');
this._mainElement.classList.add('tui-image-editor-menu-' + menuName);
this.submenu = menuName;
this[this.submenu].changeStartMode();
}
this.resizeEditor();
}
/**
* Init menu
* @private
*/
}, {
key: '_initMenu',
value: function _initMenu() {
if (this.options.initMenu) {
var evt = document.createEvent('MouseEvents');
evt.initEvent('click', true, false);
this._els[this.options.initMenu].dispatchEvent(evt);
if (this.icon) {
this.icon.registDefaultIcon();
}
}
}
/**
* Get editor dimension
* @returns {Object} - width & height of editor
* @private
*/
}, {
key: '_getEditorDimension',
value: function _getEditorDimension() {
var maxHeight = parseFloat(this._editorContainerElement.style.maxHeight);
var height = this.imageSize.newHeight > maxHeight ? maxHeight : this.imageSize.newHeight;
var maxWidth = parseFloat(this._editorContainerElement.style.maxWidth);
var width = this.imageSize.newWidth > maxWidth ? maxWidth : this.imageSize.newWidth;
return {
width: width,
height: height
};
}
/**
* Set editor position
* @param {string} menuBarPosition - top or right or bottom or left
* @private
*/
}, {
key: '_setEditorPosition',
value: function _setEditorPosition(menuBarPosition) {
var _getEditorDimension3 = this._getEditorDimension(),
width = _getEditorDimension3.width,
height = _getEditorDimension3.height;
var editorElementStyle = this._editorElement.style;
var top = 0;
var left = 0;
if (this.submenu) {
if (menuBarPosition === 'bottom') {
if (height > this._editorElementWrap.scrollHeight - 150) {
top = (height - this._editorElementWrap.scrollHeight) / 2;
} else {
top = 150 / 2 * -1;
}
} else if (menuBarPosition === 'top') {
if (height > this._editorElementWrap.offsetHeight - 150) {
top = 150 / 2 - (height - (this._editorElementWrap.offsetHeight - 150)) / 2;
} else {
top = 150 / 2;
}
} else if (menuBarPosition === 'left') {
if (width > this._editorElementWrap.offsetWidth - 248) {
left = 248 / 2 - (width - (this._editorElementWrap.offsetWidth - 248)) / 2;
} else {
left = 248 / 2;
}
} else if (menuBarPosition === 'right') {
if (width > this._editorElementWrap.scrollWidth - 248) {
left = (width - this._editorElementWrap.scrollWidth) / 2;
} else {
left = 248 / 2 * -1;
}
}
}
editorElementStyle.top = top + 'px';
editorElementStyle.left = left + 'px';
}
}]);
return Ui;
}();
exports.default = Ui;
/***/ }),
/* 75 */
/***/ (function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (_ref) {
var biImage = _ref.biImage,
commonStyle = _ref.commonStyle,
headerStyle = _ref.headerStyle,
loadButtonStyle = _ref.loadButtonStyle,
downloadButtonStyle = _ref.downloadButtonStyle,
submenuStyle = _ref.submenuStyle;
return "\n <div class=\"tui-image-editor-main-container\" style=\"" + commonStyle + "\">\n <div class=\"tui-image-editor-header\" style=\"" + headerStyle + "\">\n <div class=\"tui-image-editor-header-logo\">\n <img src=\"" + biImage + "\" />\n </div>\n <div class=\"tui-image-editor-header-buttons\">\n <button style=\"" + loadButtonStyle + "\">\n Load\n <input type=\"file\" class=\"tui-image-editor-load-btn\" />\n </button>\n <button class=\"tui-image-editor-download-btn\" style=\"" + downloadButtonStyle + "\">\n Download\n </button>\n </div>\n </div>\n <div class=\"tui-image-editor-main\">\n <div class=\"tui-image-editor-submenu\">\n <div class=\"tui-image-editor-submenu-style\" style=\"" + submenuStyle + "\"></div>\n </div>\n <div class=\"tui-image-editor-wrap\">\n <div class=\"tui-image-editor-size-wrap\">\n <div class=\"tui-image-editor-align-wrap\">\n <div class=\"tui-image-editor\"></div>\n </div>\n </div>\n </div>\n </div>\n </div>\n";
};
/***/ }),
/* 76 */
/***/ (function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (_ref) {
var biImage = _ref.biImage,
_ref$iconStyle = _ref.iconStyle,
normal = _ref$iconStyle.normal,
hover = _ref$iconStyle.hover,
disabled = _ref$iconStyle.disabled,
loadButtonStyle = _ref.loadButtonStyle,
downloadButtonStyle = _ref.downloadButtonStyle;
return "\n <div class=\"tui-image-editor-controls\">\n <div class=\"tui-image-editor-controls-logo\">\n <img src=\"" + biImage + "\" />\n </div>\n <ul class=\"tui-image-editor-menu\">\n <li id=\"tie-btn-undo\" class=\"tui-image-editor-item\" title=\"Undo\">\n <svg class=\"svg_ic-menu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-undo\" class=\"enabled\"/>\n <use xlink:href=\"" + disabled.path + "#" + disabled.name + "-ic-undo\" class=\"normal\"/>\n <use xlink:href=\"" + hover.path + "#" + hover.name + "-ic-undo\" class=\"hover\"/>\n </svg>\n </li>\n <li id=\"tie-btn-redo\" class=\"tui-image-editor-item\" title=\"Redo\">\n <svg class=\"svg_ic-menu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-redo\" class=\"enabled\"/>\n <use xlink:href=\"" + disabled.path + "#" + disabled.name + "-ic-redo\" class=\"normal\"/>\n <use xlink:href=\"" + hover.path + "#" + hover.name + "-ic-redo\" class=\"hover\"/>\n </svg>\n </li>\n <li id=\"tie-btn-reset\" class=\"tui-image-editor-item\" title=\"Reset\">\n <svg class=\"svg_ic-menu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-reset\" class=\"enabled\"/>\n <use xlink:href=\"" + disabled.path + "#" + disabled.name + "-ic-reset\" class=\"normal\"/>\n <use xlink:href=\"" + hover.path + "#" + hover.name + "-ic-reset\" class=\"hover\"/>\n </svg>\n </li>\n <li class=\"tui-image-editor-item\">\n <div class=\"tui-image-editor-icpartition\"></div>\n </li>\n <li id=\"tie-btn-delete\" class=\"tui-image-editor-item\" title=\"Delete\">\n <svg class=\"svg_ic-menu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-delete\" class=\"enabled\"/>\n <use xlink:href=\"" + disabled.path + "#" + disabled.name + "-ic-delete\" class=\"normal\"/>\n <use xlink:href=\"" + hover.path + "#" + hover.name + "-ic-delete\" class=\"hover\"/>\n </svg>\n </li>\n <li id=\"tie-btn-delete-all\" class=\"tui-image-editor-item\" title=\"Delete-all\">\n <svg class=\"svg_ic-menu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-delete-all\" class=\"enabled\"/>\n <use xlink:href=\"" + disabled.path + "#" + disabled.name + "-ic-delete-all\" class=\"normal\"/>\n <use xlink:href=\"" + hover.path + "#" + hover.name + "-ic-delete-all\" class=\"hover\"/>\n </svg>\n </li>\n <li class=\"tui-image-editor-item\">\n <div class=\"tui-image-editor-icpartition\"></div>\n </li>\n </ul>\n\n <div class=\"tui-image-editor-controls-buttons\">\n <button style=\"" + loadButtonStyle + "\">\n Load\n <input type=\"file\" class=\"tui-image-editor-load-btn\" />\n </button>\n <button class=\"tui-image-editor-download-btn\" style=\"" + downloadButtonStyle + "\">\n Download\n </button>\n </div>\n </div>\n";
};
/***/ }),
/* 77 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _tuiCodeSnippet = __webpack_require__(3);
var _util = __webpack_require__(72);
var _style = __webpack_require__(78);
var _style2 = _interopRequireDefault(_style);
var _standard = __webpack_require__(79);
var _standard2 = _interopRequireDefault(_standard);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* Theme manager
* @class
* @param {Object} customTheme - custom theme
* @ignore
*/
var Theme = function () {
function Theme(customTheme) {
_classCallCheck(this, Theme);
this.styles = this._changeToObject((0, _tuiCodeSnippet.extend)(_standard2.default, customTheme));
(0, _util.styleLoad)(this._styleMaker());
}
/**
* Get a Style cssText or StyleObject
* @param {string} type - style type
* @returns {string|object} - cssText or StyleObject
*/
_createClass(Theme, [{
key: 'getStyle',
value: function getStyle(type) {
// eslint-disable-line
var result = null;
var firstProperty = type.replace(/\..+$/, '');
var option = this.styles[type];
switch (type) {
case 'common.bi':
result = this.styles[type].image;
break;
case 'menu.icon':
case 'submenu.icon':
result = {
active: this.styles[firstProperty + '.activeIcon'],
normal: this.styles[firstProperty + '.normalIcon'],
hover: this.styles[firstProperty + '.hoverIcon'],
disabled: this.styles[firstProperty + '.disabledIcon']
};
break;
case 'submenu.label':
result = {
active: this._makeCssText(this.styles[firstProperty + '.activeLabel']),
normal: this._makeCssText(this.styles[firstProperty + '.normalLabel'])
};
break;
case 'submenu.partition':
result = {
vertical: this._makeCssText((0, _tuiCodeSnippet.extend)({}, option, { borderLeft: '1px solid ' + option.color })),
horizontal: this._makeCssText((0, _tuiCodeSnippet.extend)({}, option, { borderBottom: '1px solid ' + option.color }))
};
break;
case 'range.disabledPointer':
case 'range.disabledBar':
case 'range.disabledSubbar':
case 'range.pointer':
case 'range.bar':
case 'range.subbar':
option.backgroundColor = option.color;
result = this._makeCssText(option);
break;
default:
result = this._makeCssText(option);
break;
}
return result;
}
/**
* Make css resource
* @returns {string} - serialized css text
* @private
*/
}, {
key: '_styleMaker',
value: function _styleMaker() {
var submenuLabelStyle = this.getStyle('submenu.label');
var submenuPartitionStyle = this.getStyle('submenu.partition');
return (0, _style2.default)({
subMenuLabelActive: submenuLabelStyle.active,
subMenuLabelNormal: submenuLabelStyle.normal,
submenuPartitionVertical: submenuPartitionStyle.vertical,
submenuPartitionHorizontal: submenuPartitionStyle.horizontal,
biSize: this.getStyle('common.bisize'),
subMenuRangeTitle: this.getStyle('range.title'),
submenuRangePointer: this.getStyle('range.pointer'),
submenuRangeBar: this.getStyle('range.bar'),
submenuRangeSubbar: this.getStyle('range.subbar'),
submenuDisabledRangePointer: this.getStyle('range.disabledPointer'),
submenuDisabledRangeBar: this.getStyle('range.disabledBar'),
submenuDisabledRangeSubbar: this.getStyle('range.disabledSubbar'),
submenuRangeValue: this.getStyle('range.value'),
submenuColorpickerTitle: this.getStyle('colorpicker.title'),
submenuColorpickerButton: this.getStyle('colorpicker.button'),
submenuCheckbox: this.getStyle('checkbox'),
menuIconSize: this.getStyle('menu.iconSize'),
submenuIconSize: this.getStyle('submenu.iconSize')
});
}
/**
* Change to low dimensional object.
* @param {object} styleOptions - style object of user interface
* @returns {object} low level object for style apply
* @private
*/
}, {
key: '_changeToObject',
value: function _changeToObject(styleOptions) {
var styleObject = {};
(0, _tuiCodeSnippet.forEach)(styleOptions, function (value, key) {
var keyExplode = key.match(/^(.+)\.([a-z]+)$/i);
var property = keyExplode[1],
subProperty = keyExplode[2];
if (!styleObject[property]) {
styleObject[property] = {};
}
styleObject[property][subProperty] = value;
});
return styleObject;
}
/**
* Style object to Csstext serialize
* @param {object} styleObject - style object
* @returns {string} - css text string
* @private
*/
}, {
key: '_makeCssText',
value: function _makeCssText(styleObject) {
var _this = this;
var converterStack = [];
(0, _tuiCodeSnippet.forEach)(styleObject, function (value, key) {
if (['backgroundImage'].indexOf(key) > -1 && value !== 'none') {
value = 'url(' + value + ')';
}
converterStack.push(_this._toUnderScore(key) + ': ' + value);
});
return converterStack.join(';');
}
/**
* Camel key string to Underscore string
* @param {string} targetString - change target
* @returns {string}
* @private
*/
}, {
key: '_toUnderScore',
value: function _toUnderScore(targetString) {
return targetString.replace(/([A-Z])/g, function ($0, $1) {
return '-' + $1.toLowerCase();
});
}
}]);
return Theme;
}();
exports.default = Theme;
/***/ }),
/* 78 */
/***/ (function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (_ref) {
var subMenuLabelActive = _ref.subMenuLabelActive,
subMenuLabelNormal = _ref.subMenuLabelNormal,
subMenuRangeTitle = _ref.subMenuRangeTitle,
submenuPartitionVertical = _ref.submenuPartitionVertical,
submenuPartitionHorizontal = _ref.submenuPartitionHorizontal,
submenuCheckbox = _ref.submenuCheckbox,
submenuRangePointer = _ref.submenuRangePointer,
submenuRangeValue = _ref.submenuRangeValue,
submenuColorpickerTitle = _ref.submenuColorpickerTitle,
submenuColorpickerButton = _ref.submenuColorpickerButton,
submenuRangeBar = _ref.submenuRangeBar,
submenuRangeSubbar = _ref.submenuRangeSubbar,
submenuDisabledRangePointer = _ref.submenuDisabledRangePointer,
submenuDisabledRangeBar = _ref.submenuDisabledRangeBar,
submenuDisabledRangeSubbar = _ref.submenuDisabledRangeSubbar,
submenuIconSize = _ref.submenuIconSize,
menuIconSize = _ref.menuIconSize,
biSize = _ref.biSize;
return "\n #tie-icon-add-button.icon-bubble .tui-image-editor-button[data-icontype=\"icon-bubble\"] label,\n #tie-icon-add-button.icon-heart .tui-image-editor-button[data-icontype=\"icon-heart\"] label,\n #tie-icon-add-button.icon-location .tui-image-editor-button[data-icontype=\"icon-location\"] label,\n #tie-icon-add-button.icon-polygon .tui-image-editor-button[data-icontype=\"icon-polygon\"] label,\n #tie-icon-add-button.icon-star .tui-image-editor-button[data-icontype=\"icon-star\"] label,\n #tie-icon-add-button.icon-arrow-3 .tui-image-editor-button[data-icontype=\"icon-arrow-3\"] label,\n #tie-icon-add-button.icon-arrow-2 .tui-image-editor-button[data-icontype=\"icon-arrow-2\"] label,\n #tie-icon-add-button.icon-arrow .tui-image-editor-button[data-icontype=\"icon-arrow\"] label,\n #tie-icon-add-button.icon-bubble .tui-image-editor-button[data-icontype=\"icon-bubble\"] label,\n #tie-draw-line-select-button.line .tui-image-editor-button.line label,\n #tie-draw-line-select-button.free .tui-image-editor-button.free label,\n #tie-flip-button.flipX .tui-image-editor-button.flipX label,\n #tie-flip-button.flipY .tui-image-editor-button.flipY label,\n #tie-flip-button.resetFlip .tui-image-editor-button.resetFlip label,\n #tie-crop-button .tui-image-editor-button.apply.active label,\n #tie-shape-button.rect .tui-image-editor-button.rect label,\n #tie-shape-button.circle .tui-image-editor-button.circle label,\n #tie-shape-button.triangle .tui-image-editor-button.triangle label,\n #tie-text-effect-button .tui-image-editor-button.active label,\n #tie-text-align-button.left .tui-image-editor-button.left label,\n #tie-text-align-button.center .tui-image-editor-button.center label,\n #tie-text-align-button.right .tui-image-editor-button.right label,\n #tie-mask-apply.apply.active .tui-image-editor-button.apply label,\n .tui-image-editor-container .tui-image-editor-submenu .tui-image-editor-button:hover > label,\n .tui-image-editor-container .tui-image-editor-checkbox input + label {\n " + subMenuLabelActive + "\n }\n .tui-image-editor-container .tui-image-editor-submenu .tui-image-editor-button > label,\n .tui-image-editor-container .tui-image-editor-range-wrap.tui-image-editor-newline.short label {\n " + subMenuLabelNormal + "\n }\n .tui-image-editor-container .tui-image-editor-range-wrap label {\n " + subMenuRangeTitle + "\n }\n .tui-image-editor-container .tui-image-editor-partition > div {\n " + submenuPartitionVertical + "\n }\n .tui-image-editor-container.left .tui-image-editor-submenu .tui-image-editor-partition > div,\n .tui-image-editor-container.right .tui-image-editor-submenu .tui-image-editor-partition > div {\n " + submenuPartitionHorizontal + "\n }\n .tui-image-editor-container .tui-image-editor-checkbox input + label:before {\n " + submenuCheckbox + "\n }\n .tui-image-editor-container .tui-image-editor-checkbox input:checked + label:before {\n border: 0;\n }\n .tui-image-editor-container .tui-image-editor-virtual-range-pointer {\n " + submenuRangePointer + "\n }\n .tui-image-editor-container .tui-image-editor-virtual-range-bar {\n " + submenuRangeBar + "\n }\n .tui-image-editor-container .tui-image-editor-virtual-range-subbar {\n " + submenuRangeSubbar + "\n }\n .tui-image-editor-container .tui-image-editor-disabled .tui-image-editor-virtual-range-pointer {\n " + submenuDisabledRangePointer + "\n }\n .tui-image-editor-container .tui-image-editor-disabled .tui-image-editor-virtual-range-subbar {\n " + submenuDisabledRangeSubbar + "\n }\n .tui-image-editor-container .tui-image-editor-disabled .tui-image-editor-virtual-range-bar {\n " + submenuDisabledRangeBar + "\n }\n .tui-image-editor-container .tui-image-editor-range-value {\n " + submenuRangeValue + "\n }\n .tui-image-editor-container .tui-image-editor-submenu .tui-image-editor-button .color-picker-value + label {\n " + submenuColorpickerTitle + "\n }\n .tui-image-editor-container .tui-image-editor-submenu .tui-image-editor-button .color-picker-value {\n " + submenuColorpickerButton + "\n }\n .tui-image-editor-container .svg_ic-menu {\n " + menuIconSize + "\n }\n .tui-image-editor-container .svg_ic-submenu {\n " + submenuIconSize + "\n }\n .tui-image-editor-container .tui-image-editor-controls-logo > img,\n .tui-image-editor-container .tui-image-editor-header-logo > img {\n " + biSize + "\n }\n\n";
};
/***/ }),
/* 79 */
/***/ (function(module, exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
* @fileoverview The standard theme
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
*/
/**
* Full configuration for theme.<br>
* @typedef {object} themeConfig
* @property {string} common.bi.image - Brand icon image
* @property {string} common.bisize.width - Icon image width
* @property {string} common.bisize.height - Icon Image Height
* @property {string} common.backgroundImage - Background image
* @property {string} common.backgroundColor - Background color
* @property {string} common.border - Full area border style
* @property {string} header.backgroundImage - header area background
* @property {string} header.backgroundColor - header area background color
* @property {string} header.border - header area border style
* @property {string} loadButton.backgroundColor - load button background color
* @property {string} loadButton.border - load button border style
* @property {string} loadButton.color - load button foreground color
* @property {string} loadButton.fontFamily - load button font type
* @property {string} loadButton.fontSize - load button font size
* @property {string} downloadButton.backgroundColor - download button background color
* @property {string} downloadButton.border - download button border style
* @property {string} downloadButton.color - download button foreground color
* @property {string} downloadButton.fontFamily - download button font type
* @property {string} downloadButton.fontSize - download button font size
* @property {string} menu.normalIcon.path - Menu default icon svg bundle file path
* @property {string} menu.normalIcon.name - Menu default icon svg bundle name
* @property {string} menu.activeIcon.path - Menu active icon svg bundle file path
* @property {string} menu.activeIcon.name - Menu active icon svg bundle name
* @property {string} menu.iconSize.width - Menu icon Size Width
* @property {string} menu.iconSize.height - Menu Icon Size Height
* @property {string} submenu.backgroundColor - Sub-menu area background color
* @property {string} submenu.partition.color - Submenu partition line color
* @property {string} submenu.normalIcon.path - Submenu default icon svg bundle file path
* @property {string} submenu.normalIcon.name - Submenu default icon svg bundle name
* @property {string} submenu.activeIcon.path - Submenu active icon svg bundle file path
* @property {string} submenu.activeIcon.name - Submenu active icon svg bundle name
* @property {string} submenu.iconSize.width - Submenu icon Size Width
* @property {string} submenu.iconSize.height - Submenu Icon Size Height
* @property {string} submenu.normalLabel.color - Submenu default label color
* @property {string} submenu.normalLabel.fontWeight - Sub Menu Default Label Font Thickness
* @property {string} submenu.activeLabel.color - Submenu active label color
* @property {string} submenu.activeLabel.fontWeight - Submenu active label Font thickness
* @property {string} checkbox.border - Checkbox border style
* @property {string} checkbox.backgroundColor - Checkbox background color
* @property {string} range.pointer.color - range control pointer color
* @property {string} range.bar.color - range control bar color
* @property {string} range.subbar.color - range control subbar color
* @property {string} range.value.color - range number box font color
* @property {string} range.value.fontWeight - range number box font thickness
* @property {string} range.value.fontSize - range number box font size
* @property {string} range.value.border - range number box border style
* @property {string} range.value.backgroundColor - range number box background color
* @property {string} range.title.color - range title font color
* @property {string} range.title.fontWeight - range title font weight
* @property {string} colorpicker.button.border - colorpicker button border style
* @property {string} colorpicker.title.color - colorpicker button title font color
* @example
// default keys and styles
var customTheme = {
'common.bi.image': 'https://uicdn.toast.com/toastui/img/tui-image-editor-bi.png',
'common.bisize.width': '251px',
'common.bisize.height': '21px',
'common.backgroundImage': 'none',
'common.backgroundColor': '#1e1e1e',
'common.border': '0px',
// header
'header.backgroundImage': 'none',
'header.backgroundColor': 'transparent',
'header.border': '0px',
// load button
'loadButton.backgroundColor': '#fff',
'loadButton.border': '1px solid #ddd',
'loadButton.color': '#222',
'loadButton.fontFamily': 'NotoSans, sans-serif',
'loadButton.fontSize': '12px',
// download button
'downloadButton.backgroundColor': '#fdba3b',
'downloadButton.border': '1px solid #fdba3b',
'downloadButton.color': '#fff',
'downloadButton.fontFamily': 'NotoSans, sans-serif',
'downloadButton.fontSize': '12px',
// main icons
'menu.normalIcon.path': '../dist/svg/icon-b.svg',
'menu.normalIcon.name': 'icon-b',
'menu.activeIcon.path': '../dist/svg/icon-a.svg',
'menu.activeIcon.name': 'icon-a',
'menu.iconSize.width': '24px',
'menu.iconSize.height': '24px',
// submenu primary color
'submenu.backgroundColor': '#1e1e1e',
'submenu.partition.color': '#858585',
// submenu icons
'submenu.normalIcon.path': '../dist/svg/icon-a.svg',
'submenu.normalIcon.name': 'icon-a',
'submenu.activeIcon.path': '../dist/svg/icon-c.svg',
'submenu.activeIcon.name': 'icon-c',
'submenu.iconSize.width': '32px',
'submenu.iconSize.height': '32px',
// submenu labels
'submenu.normalLabel.color': '#858585',
'submenu.normalLabel.fontWeight': 'lighter',
'submenu.activeLabel.color': '#fff',
'submenu.activeLabel.fontWeight': 'lighter',
// checkbox style
'checkbox.border': '1px solid #ccc',
'checkbox.backgroundColor': '#fff',
// rango style
'range.pointer.color': '#fff',
'range.bar.color': '#666',
'range.subbar.color': '#d1d1d1',
'range.value.color': '#fff',
'range.value.fontWeight': 'lighter',
'range.value.fontSize': '11px',
'range.value.border': '1px solid #353535',
'range.value.backgroundColor': '#151515',
'range.title.color': '#fff',
'range.title.fontWeight': 'lighter',
// colorpicker style
'colorpicker.button.border': '1px solid #1e1e1e',
'colorpicker.title.color': '#fff'
};
*/
exports.default = {
'common.bi.image': 'https://uicdn.toast.com/toastui/img/tui-image-editor-bi.png',
'common.bisize.width': '251px',
'common.bisize.height': '21px',
'common.backgroundImage': 'none',
'common.backgroundColor': '#1e1e1e',
'common.border': '0px',
// header
'header.backgroundImage': 'none',
'header.backgroundColor': 'transparent',
'header.border': '0px',
// load button
'loadButton.backgroundColor': '#fff',
'loadButton.border': '1px solid #ddd',
'loadButton.color': '#222',
'loadButton.fontFamily': '"Noto Sans", sans-serif',
'loadButton.fontSize': '12px',
// download button
'downloadButton.backgroundColor': '#fdba3b',
'downloadButton.border': '1px solid #fdba3b',
'downloadButton.color': '#fff',
'downloadButton.fontFamily': '"Noto Sans", sans-serif',
'downloadButton.fontSize': '12px',
// main icons
'menu.normalIcon.path': 'icon-d.svg',
'menu.normalIcon.name': 'icon-d',
'menu.activeIcon.path': 'icon-b.svg',
'menu.activeIcon.name': 'icon-b',
'menu.disabledIcon.path': 'icon-a.svg',
'menu.disabledIcon.name': 'icon-a',
'menu.hoverIcon.path': 'icon-c.svg',
'menu.hoverIcon.name': 'icon-c',
'menu.iconSize.width': '24px',
'menu.iconSize.height': '24px',
// submenu primary color
'submenu.backgroundColor': 'transparent',
'submenu.partition.color': '#858585',
// submenu icons
'submenu.normalIcon.path': 'icon-a.svg',
'submenu.normalIcon.name': 'icon-a',
'submenu.activeIcon.path': 'icon-c.svg',
'submenu.activeIcon.name': 'icon-c',
'submenu.iconSize.width': '32px',
'submenu.iconSize.height': '32px',
// submenu labels
'submenu.normalLabel.color': '#858585',
'submenu.normalLabel.fontWeight': 'lighter',
'submenu.activeLabel.color': '#fff',
'submenu.activeLabel.fontWeight': 'lighter',
// checkbox style
'checkbox.border': '1px solid #ccc',
'checkbox.backgroundColor': '#fff',
// rango style
'range.pointer.color': '#fff',
'range.bar.color': '#666',
'range.subbar.color': '#d1d1d1',
'range.disabledPointer.color': 'red',
'range.disabledBar.color': 'blue',
'range.disabledSubbar.color': 'red',
'range.value.color': '#fff',
'range.value.fontWeight': 'lighter',
'range.value.fontSize': '11px',
'range.value.border': '1px solid #353535',
'range.value.backgroundColor': '#151515',
'range.title.color': '#fff',
'range.title.fontWeight': 'lighter',
// colorpicker style
'colorpicker.button.border': '1px solid #1e1e1e',
'colorpicker.title.color': '#fff'
};
/***/ }),
/* 80 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _colorpicker = __webpack_require__(81);
var _colorpicker2 = _interopRequireDefault(_colorpicker);
var _range = __webpack_require__(83);
var _range2 = _interopRequireDefault(_range);
var _submenuBase = __webpack_require__(84);
var _submenuBase2 = _interopRequireDefault(_submenuBase);
var _shape = __webpack_require__(85);
var _shape2 = _interopRequireDefault(_shape);
var _util = __webpack_require__(72);
var _consts = __webpack_require__(73);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var SHAPE_DEFAULT_OPTION = {
stroke: '#ffbb3b',
fill: '',
strokeWidth: 3
};
/**
* Shape ui class
* @class
* @ignore
*/
var Shape = function (_Submenu) {
_inherits(Shape, _Submenu);
function Shape(subMenuElement, _ref) {
var iconStyle = _ref.iconStyle,
menuBarPosition = _ref.menuBarPosition;
_classCallCheck(this, Shape);
var _this = _possibleConstructorReturn(this, (Shape.__proto__ || Object.getPrototypeOf(Shape)).call(this, subMenuElement, {
name: 'shape',
iconStyle: iconStyle,
menuBarPosition: menuBarPosition,
templateHtml: _shape2.default
}));
_this.type = null;
_this.options = SHAPE_DEFAULT_OPTION;
_this._els = {
shapeSelectButton: _this.selector('#tie-shape-button'),
shapeColorButton: _this.selector('#tie-shape-color-button'),
strokeRange: new _range2.default(_this.selector('#tie-stroke-range'), _consts.defaultShapeStrokeValus),
strokeRangeValue: _this.selector('#tie-stroke-range-value'),
fillColorpicker: new _colorpicker2.default(_this.selector('#tie-color-fill'), '', _this.toggleDirection),
strokeColorpicker: new _colorpicker2.default(_this.selector('#tie-color-stroke'), '#ffbb3b', _this.toggleDirection)
};
_this.colorPickerControls.push(_this._els.fillColorpicker);
_this.colorPickerControls.push(_this._els.strokeColorpicker);
return _this;
}
/**
* Add event for shape
* @param {Object} actions - actions for shape
* @param {Function} actions.changeShape - change shape mode
* @param {Function} actions.setDrawingShape - set dreawing shape
*/
_createClass(Shape, [{
key: 'addEvent',
value: function addEvent(actions) {
this.actions = actions;
this._els.shapeSelectButton.addEventListener('click', this._changeShapeHandler.bind(this));
this._els.strokeRange.on('change', this._changeStrokeRangeHandler.bind(this));
this._els.fillColorpicker.on('change', this._changeFillColorHandler.bind(this));
this._els.strokeColorpicker.on('change', this._changeStrokeColorHandler.bind(this));
this._els.fillColorpicker.on('changeShow', this.colorPickerChangeShow.bind(this));
this._els.strokeColorpicker.on('changeShow', this.colorPickerChangeShow.bind(this));
this._els.strokeRangeValue.value = this._els.strokeRange.value;
this._els.strokeRangeValue.setAttribute('readonly', true);
}
/**
* Set Shape status
* @param {Object} options - options of shape status
* @param {string} strokeWidth - stroke width
* @param {string} strokeColor - stroke color
* @param {string} fillColor - fill color
*/
}, {
key: 'setShapeStatus',
value: function setShapeStatus(_ref2) {
var strokeWidth = _ref2.strokeWidth,
strokeColor = _ref2.strokeColor,
fillColor = _ref2.fillColor;
this._els.strokeRange.value = strokeWidth;
this._els.strokeRange.trigger('change');
this._els.strokeColorpicker.color = strokeColor;
this._els.fillColorpicker.color = fillColor;
this.options.stroke = strokeColor;
this.options.fill = fillColor;
this.options.strokeWidth = strokeWidth;
}
/**
* Executed when the menu starts.
*/
}, {
key: 'changeStartMode',
value: function changeStartMode() {
this.actions.stopDrawingMode();
}
/**
* Returns the menu to its default state.
*/
}, {
key: 'changeStandbyMode',
value: function changeStandbyMode() {
this.type = null;
this.actions.changeSelectableAll(true);
this._els.shapeSelectButton.classList.remove('circle');
this._els.shapeSelectButton.classList.remove('triangle');
this._els.shapeSelectButton.classList.remove('rect');
}
/**
* set range stroke max value
* @param {number} maxValue - expect max value for change
*/
}, {
key: 'setMaxStrokeValue',
value: function setMaxStrokeValue(maxValue) {
var strokeMaxValue = maxValue;
if (strokeMaxValue <= 0) {
strokeMaxValue = _consts.defaultShapeStrokeValus.max;
}
this._els.strokeRange.max = strokeMaxValue;
}
/**
* Set stroke value
* @param {number} value - expect value for strokeRange change
*/
}, {
key: 'setStrokeValue',
value: function setStrokeValue(value) {
this._els.strokeRange.value = value;
this._els.strokeRange.trigger('change');
}
/**
* Get stroke value
* @returns {number} - stroke range value
*/
}, {
key: 'getStrokeValue',
value: function getStrokeValue() {
return this._els.strokeRange.value;
}
/**
* Change icon color
* @param {object} event - add button event object
* @private
*/
}, {
key: '_changeShapeHandler',
value: function _changeShapeHandler(event) {
var button = event.target.closest('.tui-image-editor-button');
if (button) {
this.actions.stopDrawingMode();
this.actions.discardSelection();
var shapeType = this.getButtonType(button, ['circle', 'triangle', 'rect']);
if (this.type === shapeType) {
this.changeStandbyMode();
return;
}
this.changeStandbyMode();
this.type = shapeType;
event.currentTarget.classList.add(shapeType);
this.actions.changeSelectableAll(false);
this.actions.modeChange('shape');
}
}
/**
* Change stroke range
* @param {number} value - stroke range value
* @private
*/
}, {
key: '_changeStrokeRangeHandler',
value: function _changeStrokeRangeHandler(value) {
this.options.strokeWidth = (0, _util.toInteger)(value);
this._els.strokeRangeValue.value = (0, _util.toInteger)(value);
this.actions.changeShape({
strokeWidth: value
});
this.actions.setDrawingShape(this.type, this.options);
}
/**
* Change shape color
* @param {string} color - fill color
* @private
*/
}, {
key: '_changeFillColorHandler',
value: function _changeFillColorHandler(color) {
color = color || 'transparent';
this.options.fill = color;
this.actions.changeShape({
fill: color
});
}
/**
* Change shape stroke color
* @param {string} color - fill color
* @private
*/
}, {
key: '_changeStrokeColorHandler',
value: function _changeStrokeColorHandler(color) {
color = color || 'transparent';
this.options.stroke = color;
this.actions.changeShape({
stroke: color
});
}
}]);
return Shape;
}(_submenuBase2.default);
exports.default = Shape;
/***/ }),
/* 81 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _tuiCodeSnippet = __webpack_require__(3);
var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet);
var _tuiColorPicker = __webpack_require__(82);
var _tuiColorPicker2 = _interopRequireDefault(_tuiColorPicker);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var PICKER_COLOR = ['#000000', '#2a2a2a', '#545454', '#7e7e7e', '#a8a8a8', '#d2d2d2', '#ffffff', '', '#ff4040', '#ff6518', '#ffbb3b', '#03bd9e', '#00a9ff', '#515ce6', '#9e5fff', '#ff5583'];
/**
* Colorpicker control class
* @class
* @ignore
*/
var Colorpicker = function () {
function Colorpicker(colorpickerElement) {
var defaultColor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '#7e7e7e';
var toggleDirection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'up';
_classCallCheck(this, Colorpicker);
var title = colorpickerElement.getAttribute('title');
this._show = false;
this._colorpickerElement = colorpickerElement;
this._toggleDirection = toggleDirection;
this._makePickerButtonElement(colorpickerElement, defaultColor);
this._makePickerLayerElement(colorpickerElement, title);
this._color = defaultColor;
this.picker = _tuiColorPicker2.default.create({
container: this.pickerElement,
preset: PICKER_COLOR,
color: defaultColor
});
this._addEvent(colorpickerElement);
}
/**
* Get color
* @returns {Number} color value
*/
_createClass(Colorpicker, [{
key: '_changeColorElement',
/**
* Change color element
* @param {string} color color value
* #private
*/
value: function _changeColorElement(color) {
if (color) {
this.colorElement.classList.remove('transparent');
this.colorElement.style.backgroundColor = color;
} else {
this.colorElement.style.backgroundColor = '#fff';
this.colorElement.classList.add('transparent');
}
}
/**
* Make picker button element
* @param {HTMLElement} colorpickerElement color picker element
* @param {string} defaultColor color value
* @private
*/
}, {
key: '_makePickerButtonElement',
value: function _makePickerButtonElement(colorpickerElement, defaultColor) {
colorpickerElement.classList.add('tui-image-editor-button');
this.colorElement = document.createElement('div');
this.colorElement.className = 'color-picker-value';
if (defaultColor) {
this.colorElement.style.backgroundColor = defaultColor;
} else {
this.colorElement.classList.add('transparent');
}
}
/**
* Make picker layer element
* @param {HTMLElement} colorpickerElement color picker element
* @param {string} title picker title
* @private
*/
}, {
key: '_makePickerLayerElement',
value: function _makePickerLayerElement(colorpickerElement, title) {
var label = document.createElement('label');
var triangle = document.createElement('div');
this.pickerControl = document.createElement('div');
this.pickerControl.className = 'color-picker-control';
this.pickerElement = document.createElement('div');
this.pickerElement.className = 'color-picker';
label.innerHTML = title;
triangle.className = 'triangle';
this.pickerControl.appendChild(this.pickerElement);
this.pickerControl.appendChild(triangle);
colorpickerElement.appendChild(this.pickerControl);
colorpickerElement.appendChild(this.colorElement);
colorpickerElement.appendChild(label);
}
/**
* Add event
* @param {HTMLElement} colorpickerElement color picker element
* @private
*/
}, {
key: '_addEvent',
value: function _addEvent(colorpickerElement) {
var _this = this;
this.picker.on('selectColor', function (value) {
_this._changeColorElement(value.color);
_this._color = value.color;
_this.fire('change', value.color);
});
colorpickerElement.addEventListener('click', function (event) {
_this._show = !_this._show;
_this.pickerControl.style.display = _this._show ? 'block' : 'none';
_this._setPickerControlPosition();
_this.fire('changeShow', _this);
event.stopPropagation();
});
document.body.addEventListener('click', function () {
_this.hide();
});
}
}, {
key: 'hide',
value: function hide() {
this._show = false;
this.pickerControl.style.display = 'none';
}
/**
* Set picker control position
* @private
*/
}, {
key: '_setPickerControlPosition',
value: function _setPickerControlPosition() {
var controlStyle = this.pickerControl.style;
var halfPickerWidth = this._colorpickerElement.clientWidth / 2 + 2;
var left = this.pickerControl.offsetWidth / 2 - halfPickerWidth;
var top = (this.pickerControl.offsetHeight + 10) * -1;
if (this._toggleDirection === 'down') {
top = 30;
}
controlStyle.top = top + 'px';
controlStyle.left = '-' + left + 'px';
}
}, {
key: 'color',
get: function get() {
return this._color;
}
/**
* Set color
* @param {string} color color value
*/
,
set: function set(color) {
this._color = color;
this._changeColorElement(color);
}
}]);
return Colorpicker;
}();
_tuiCodeSnippet2.default.CustomEvents.mixin(Colorpicker);
exports.default = Colorpicker;
/***/ }),
/* 82 */
/***/ (function(module, exports, __webpack_require__) {
/*!
* Toast UI Colorpicker
* @version 2.2.0
* @author NHNEnt FE Development Team <dl_javascript@nhnent.com>
* @license MIT
*/
(function webpackUniversalModuleDefinition(root, factory) {
if(true)
module.exports = factory(__webpack_require__(3));
else if(typeof define === 'function' && define.amd)
define(["tui-code-snippet"], factory);
else if(typeof exports === 'object')
exports["colorPicker"] = factory(require("tui-code-snippet"));
else
root["tui"] = root["tui"] || {}, root["tui"]["colorPicker"] = factory((root["tui"] && root["tui"]["util"]));
})(this, function(__WEBPACK_EXTERNAL_MODULE_8__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "dist";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
__webpack_require__(1);
module.exports = __webpack_require__(6);
/***/ }),
/* 1 */
/***/ (function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ }),
/* 2 */,
/* 3 */,
/* 4 */,
/* 5 */,
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var domutil = __webpack_require__(7);
var domevent = __webpack_require__(9);
var Collection = __webpack_require__(10);
var View = __webpack_require__(11);
var Drag = __webpack_require__(12);
var create = __webpack_require__(13);
var Palette = __webpack_require__(16);
var Slider = __webpack_require__(18);
var colorutil = __webpack_require__(14);
var svgvml = __webpack_require__(19);
var colorPicker = {
domutil: domutil,
domevent: domevent,
Collection: Collection,
View: View,
Drag: Drag,
create: create,
Palette: Palette,
Slider: Slider,
colorutil: colorutil,
svgvml: svgvml
};
module.exports = colorPicker;
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
/**
* @fileoverview Utility modules for manipulate DOM elements.
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
*/
'use strict';
var snippet = __webpack_require__(8);
var domevent = __webpack_require__(9);
var Collection = __webpack_require__(10);
var util = snippet,
posKey = '_pos',
supportSelectStart = 'onselectstart' in document,
prevSelectStyle = '',
domutil,
userSelectProperty;
var CSS_AUTO_REGEX = /^auto$|^$|%/;
function trim(str) {
return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}
domutil = {
/**
* Create DOM element and return it.
* @param {string} tagName Tag name to append.
* @param {HTMLElement} [container] HTML element will be parent to created element.
* if not supplied, will use **document.body**
* @param {string} [className] Design class names to appling created element.
* @returns {HTMLElement} HTML element created.
*/
appendHTMLElement: function (tagName, container, className) {
var el;
className = className || '';
el = document.createElement(tagName);
el.className = className;
if (container) {
container.appendChild(el);
} else {
document.body.appendChild(el);
}
return el;
},
/**
* Remove element from parent node.
* @param {HTMLElement} el - element to remove.
*/
remove: function (el) {
if (el && el.parentNode) {
el.parentNode.removeChild(el);
}
},
/**
* Get element by id
* @param {string} id element id attribute
* @returns {HTMLElement} element
*/
get: function (id) {
return document.getElementById(id);
},
/**
* Check supplied element is matched selector.
* @param {HTMLElement} el - element to check
* @param {string} selector - selector string to check
* @returns {boolean} match?
*/
_matcher: function (el, selector) {
var cssClassSelector = /^\./,
idSelector = /^#/;
if (cssClassSelector.test(selector)) {
return domutil.hasClass(el, selector.replace('.', ''));
} else if (idSelector.test(selector)) {
return el.id === selector.replace('#', '');
}
return el.nodeName.toLowerCase() === selector.toLowerCase();
},
/**
* Find DOM element by specific selectors.
* below three selector only supported.
*
* 1. css selector
* 2. id selector
* 3. nodeName selector
* @param {string} selector selector
* @param {(HTMLElement|string)} [root] You can assign root element to find. if not supplied, document.body will use.
* @param {boolean|function} [multiple=false] - set true then return all elements that meet condition, if set function then use it filter function.
* @returns {HTMLElement} HTML element finded.
*/
find: function (selector, root, multiple) {
var result = [],
found = false,
isFirst = util.isUndefined(multiple) || multiple === false,
isFilter = util.isFunction(multiple);
if (util.isString(root)) {
root = domutil.get(root);
}
root = root || window.document.body;
function recurse(el, selector) {
var childNodes = el.childNodes,
i = 0,
len = childNodes.length,
cursor;
for (; i < len; i += 1) {
cursor = childNodes[i];
if (cursor.nodeName === '#text') {
continue;
}
if (domutil._matcher(cursor, selector)) {
if (isFilter && multiple(cursor) || !isFilter) {
result.push(cursor);
}
if (isFirst) {
found = true;
break;
}
} else if (cursor.childNodes.length > 0) {
recurse(cursor, selector);
if (found) {
break;
}
}
}
}
recurse(root, selector);
return isFirst ? result[0] || null : result;
},
/**
* Find parent element recursively.
* @param {HTMLElement} el - base element to start find.
* @param {string} selector - selector string for find
* @returns {HTMLElement} - element finded or undefined.
*/
closest: function (el, selector) {
var parent = el.parentNode;
if (domutil._matcher(el, selector)) {
return el;
}
while (parent && parent !== window.document.body) {
if (domutil._matcher(parent, selector)) {
return parent;
}
parent = parent.parentNode;
}
},
/**
* Return texts inside element.
* @param {HTMLElement} el target element
* @returns {string} text inside node
*/
text: function (el) {
var ret = '',
i = 0,
nodeType = el.nodeType;
if (nodeType) {
if (nodeType === 1 || nodeType === 9 || nodeType === 11) {
// nodes that available contain other nodes
if (typeof el.textContent === 'string') {
return el.textContent;
}
for (el = el.firstChild; el; el = el.nextSibling) {
ret += domutil.text(el);
}
} else if (nodeType === 3 || nodeType === 4) {
// TEXT, CDATA SECTION
return el.nodeValue;
}
} else {
for (; el[i]; i += 1) {
ret += domutil.text(el[i]);
}
}
return ret;
},
/**
* Set data attribute to target element
* @param {HTMLElement} el - element to set data attribute
* @param {string} key - key
* @param {string|number} data - data value
*/
setData: function (el, key, data) {
if ('dataset' in el) {
el.dataset[key] = data;
return;
}
el.setAttribute('data-' + key, data);
},
/**
* Get data value from data-attribute
* @param {HTMLElement} el - target element
* @param {string} key - key
* @returns {string} value
*/
getData: function (el, key) {
if ('dataset' in el) {
return el.dataset[key];
}
return el.getAttribute('data-' + key);
},
/**
* Check element has specific design class name.
* @param {HTMLElement} el target element
* @param {string} name css class
* @returns {boolean} return true when element has that css class name
*/
hasClass: function (el, name) {
var className;
if (!util.isUndefined(el.classList)) {
return el.classList.contains(name);
}
className = domutil.getClass(el);
return className.length > 0 && new RegExp('(^|\\s)' + name + '(\\s|$)').test(className);
},
/**
* Add design class to HTML element.
* @param {HTMLElement} el target element
* @param {string} name css class name
*/
addClass: function (el, name) {
var className;
if (!util.isUndefined(el.classList)) {
util.forEachArray(name.split(' '), function (value) {
el.classList.add(value);
});
} else if (!domutil.hasClass(el, name)) {
className = domutil.getClass(el);
domutil.setClass(el, (className ? className + ' ' : '') + name);
}
},
/**
*
* Overwrite design class to HTML element.
* @param {HTMLElement} el target element
* @param {string} name css class name
*/
setClass: function (el, name) {
if (util.isUndefined(el.className.baseVal)) {
el.className = name;
} else {
el.className.baseVal = name;
}
},
/**
* Element에 cssClass속성을 제거하는 메서드
* Remove specific design class from HTML element.
* @param {HTMLElement} el target element
* @param {string} name class name to remove
*/
removeClass: function (el, name) {
var removed = '';
if (!util.isUndefined(el.classList)) {
el.classList.remove(name);
} else {
removed = (' ' + domutil.getClass(el) + ' ').replace(' ' + name + ' ', ' ');
domutil.setClass(el, trim(removed));
}
},
/**
* Get HTML element's design classes.
* @param {HTMLElement} el target element
* @returns {string} element css class name
*/
getClass: function (el) {
if (!el || !el.className) {
return '';
}
return util.isUndefined(el.className.baseVal) ? el.className : el.className.baseVal;
},
/**
* Get specific CSS style value from HTML element.
* @param {HTMLElement} el target element
* @param {string} style css attribute name
* @returns {(string|null)} css style value
*/
getStyle: function (el, style) {
var value = el.style[style] || el.currentStyle && el.currentStyle[style],
css;
if ((!value || value === 'auto') && document.defaultView) {
css = document.defaultView.getComputedStyle(el, null);
value = css ? css[style] : null;
}
return value === 'auto' ? null : value;
},
/**
* get element's computed style values.
*
* in lower IE8. use polyfill function that return object. it has only one function 'getPropertyValue'
* @param {HTMLElement} el - element want to get style.
* @returns {object} virtual CSSStyleDeclaration object.
*/
getComputedStyle: function (el) {
var defaultView = document.defaultView;
if (!defaultView || !defaultView.getComputedStyle) {
return {
getPropertyValue: function (prop) {
var re = /(\-([a-z]){1})/g;
if (prop === 'float') {
prop = 'styleFloat';
}
if (re.test(prop)) {
prop = prop.replace(re, function () {
return arguments[2].toUpperCase();
});
}
return el.currentStyle[prop] ? el.currentStyle[prop] : null;
}
};
}
return document.defaultView.getComputedStyle(el);
},
/**
* Set position CSS style.
* @param {HTMLElement} el target element
* @param {number} [x=0] left pixel value.
* @param {number} [y=0] top pixel value.
*/
setPosition: function (el, x, y) {
x = util.isUndefined(x) ? 0 : x;
y = util.isUndefined(y) ? 0 : y;
el[posKey] = [x, y];
el.style.left = x + 'px';
el.style.top = y + 'px';
},
/**
* Get position from HTML element.
* @param {HTMLElement} el target element
* @param {boolean} [clear=false] clear cache before calculating position.
* @returns {number[]} point
*/
getPosition: function (el, clear) {
var left, top, bound;
if (clear) {
el[posKey] = null;
}
if (el[posKey]) {
return el[posKey];
}
left = 0;
top = 0;
if ((CSS_AUTO_REGEX.test(el.style.left) || CSS_AUTO_REGEX.test(el.style.top)) && 'getBoundingClientRect' in el) {
// 엘리먼트의 left또는 top이 'auto'일 때 수단
bound = el.getBoundingClientRect();
left = bound.left;
top = bound.top;
} else {
left = parseFloat(el.style.left || 0);
top = parseFloat(el.style.top || 0);
}
return [left, top];
},
/**
* Return element's size
* @param {HTMLElement} el target element
* @returns {number[]} width, height
*/
getSize: function (el) {
var bound,
width = domutil.getStyle(el, 'width'),
height = domutil.getStyle(el, 'height');
if ((CSS_AUTO_REGEX.test(width) || CSS_AUTO_REGEX.test(height)) && 'getBoundingClientRect' in el) {
bound = el.getBoundingClientRect();
width = bound.width;
height = bound.height;
} else {
width = parseFloat(width || 0);
height = parseFloat(height || 0);
}
return [width, height];
},
/**
* Check specific CSS style is available.
* @param {array} props property name to testing
* @returns {(string|boolean)} return true when property is available
* @example
* var props = ['transform', '-webkit-transform'];
* domutil.testProp(props); // 'transform'
*/
testProp: function (props) {
var style = document.documentElement.style,
i = 0,
len = props.length;
for (; i < len; i += 1) {
if (props[i] in style) {
return props[i];
}
}
return false;
},
/**
* Get form data
* @param {HTMLFormElement} formElement - form element to extract data
* @returns {object} form data
*/
getFormData: function (formElement) {
var groupedByName = new Collection(function () {
return this.length;
}),
noDisabledFilter = function (el) {
return !el.disabled;
},
output = {};
groupedByName.add.apply(groupedByName, domutil.find('input', formElement, noDisabledFilter).concat(domutil.find('select', formElement, noDisabledFilter)).concat(domutil.find('textarea', formElement, noDisabledFilter)));
groupedByName = groupedByName.groupBy(function (el) {
return el && el.getAttribute('name') || '_other';
});
util.forEach(groupedByName, function (elements, name) {
if (name === '_other') {
return;
}
elements.each(function (el) {
var nodeName = el.nodeName.toLowerCase(),
type = el.type,
result = [];
if (type === 'radio') {
result = [elements.find(function (el) {
return el.checked;
}).toArray().pop()];
} else if (type === 'checkbox') {
result = elements.find(function (el) {
return el.checked;
}).toArray();
} else if (nodeName === 'select') {
elements.find(function (el) {
return !!el.childNodes.length;
}).each(function (el) {
result = result.concat(domutil.find('option', el, function (opt) {
return opt.selected;
}));
});
} else {
result = elements.find(function (el) {
return el.value !== '';
}).toArray();
}
result = util.map(result, function (el) {
return el.value;
});
if (!result.length) {
result = '';
} else if (result.length === 1) {
result = result[0];
}
output[name] = result;
});
});
return output;
}
};
userSelectProperty = domutil.testProp(['userSelect', 'WebkitUserSelect', 'OUserSelect', 'MozUserSelect', 'msUserSelect']);
/**
* Disable browser's text selection behaviors.
* @method
*/
domutil.disableTextSelection = function () {
if (supportSelectStart) {
return function () {
domevent.on(window, 'selectstart', domevent.preventDefault);
};
}
return function () {
var style = document.documentElement.style;
prevSelectStyle = style[userSelectProperty];
style[userSelectProperty] = 'none';
};
}();
/**
* Enable browser's text selection behaviors.
* @method
*/
domutil.enableTextSelection = function () {
if (supportSelectStart) {
return function () {
domevent.off(window, 'selectstart', domevent.preventDefault);
};
}
return function () {
document.documentElement.style[userSelectProperty] = prevSelectStyle;
};
}();
/**
* Disable browser's image drag behaviors.
*/
domutil.disableImageDrag = function () {
domevent.on(window, 'dragstart', domevent.preventDefault);
};
/**
* Enable browser's image drag behaviors.
*/
domutil.enableImageDrag = function () {
domevent.off(window, 'dragstart', domevent.preventDefault);
};
/**
* Replace matched property with template
* @param {string} template - String of template
* @param {Object} propObj - Properties
* @returns {string} Replaced template string
*/
domutil.applyTemplate = function (template, propObj) {
var newTemplate = template.replace(/\{\{(\w*)\}\}/g, function (value, prop) {
return propObj.hasOwnProperty(prop) ? propObj[prop] : '';
});
return newTemplate;
};
module.exports = domutil;
/***/ }),
/* 8 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_8__;
/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
/**
* @fileoverview Utility module for handling DOM events.
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
*/
'use strict';
var snippet = __webpack_require__(8);
var util = snippet,
browser = util.browser,
eventKey = '_evt',
DRAG = {
START: ['touchstart', 'mousedown'],
END: {
mousedown: 'mouseup',
touchstart: 'touchend',
pointerdown: 'touchend',
MSPointerDown: 'touchend'
},
MOVE: {
mousedown: 'mousemove',
touchstart: 'touchmove',
pointerdown: 'touchmove',
MSPointerDown: 'touchmove'
}
};
var domevent = {
/**
* Bind dom events.
* @param {HTMLElement} obj HTMLElement to bind events.
* @param {(string|object)} types Space splitted events names or eventName:handler object.
* @param {*} fn handler function or context for handler method.
* @param {*} [context] context object for handler method.
*/
on: function (obj, types, fn, context) {
if (util.isString(types)) {
util.forEach(types.split(' '), function (type) {
domevent._on(obj, type, fn, context);
});
return;
}
util.forEachOwnProperties(types, function (handler, type) {
domevent._on(obj, type, handler, fn);
});
},
/**
* DOM event binding.
* @param {HTMLElement} obj HTMLElement to bind events.
* @param {String} type The name of events.
* @param {*} fn handler function
* @param {*} [context] context object for handler method.
* @private
*/
_on: function (obj, type, fn, context) {
var id, handler, originHandler;
id = type + util.stamp(fn) + (context ? '_' + util.stamp(context) : '');
if (obj[eventKey] && obj[eventKey][id]) {
return;
}
handler = function (e) {
fn.call(context || obj, e || window.event);
};
originHandler = handler;
if ('addEventListener' in obj) {
if (type === 'mouseenter' || type === 'mouseleave') {
handler = function (e) {
e = e || window.event;
if (!domevent._checkMouse(obj, e)) {
return;
}
originHandler(e);
};
obj.addEventListener(type === 'mouseenter' ? 'mouseover' : 'mouseout', handler, false);
} else {
if (type === 'mousewheel') {
obj.addEventListener('DOMMouseScroll', handler, false);
}
obj.addEventListener(type, handler, false);
}
} else if ('attachEvent' in obj) {
obj.attachEvent('on' + type, handler);
}
obj[eventKey] = obj[eventKey] || {};
obj[eventKey][id] = handler;
},
/**
* Unbind DOM Event handler.
* @param {HTMLElement} obj HTMLElement to unbind.
* @param {(string|object)} types Space splitted events names or eventName:handler object.
* @param {*} fn handler function or context for handler method.
* @param {*} [context] context object for handler method.
*/
off: function (obj, types, fn, context) {
if (util.isString(types)) {
util.forEach(types.split(' '), function (type) {
domevent._off(obj, type, fn, context);
});
return;
}
util.forEachOwnProperties(types, function (handler, type) {
domevent._off(obj, type, handler, fn);
});
},
/**
* Unbind DOM event handler.
* @param {HTMLElement} obj HTMLElement to unbind.
* @param {String} type The name of event to unbind.
* @param {function()} fn Event handler that supplied when binding.
* @param {*} context context object that supplied when binding.
* @private
*/
_off: function (obj, type, fn, context) {
var id = type + util.stamp(fn) + (context ? '_' + util.stamp(context) : ''),
handler = obj[eventKey] && obj[eventKey][id];
if (!handler) {
return;
}
if ('removeEventListener' in obj) {
if (type === 'mouseenter' || type === 'mouseleave') {
obj.removeEventListener(type === 'mouseenter' ? 'mouseover' : 'mouseout', handler, false);
} else {
if (type === 'mousewheel') {
obj.removeEventListener('DOMMouseScroll', handler, false);
}
obj.removeEventListener(type, handler, false);
}
} else if ('detachEvent' in obj) {
try {
obj.detachEvent('on' + type, handler);
} catch (e) {} //eslint-disable-line
}
delete obj[eventKey][id];
if (util.keys(obj[eventKey]).length) {
return;
}
// throw exception when deleting host object's property in below IE8
if (util.browser.msie && util.browser.version < 9) {
obj[eventKey] = null;
return;
}
delete obj[eventKey];
},
/**
* Bind DOM event. this event will unbind after invokes.
* @param {HTMLElement} obj HTMLElement to bind events.
* @param {(string|object)} types Space splitted events names or eventName:handler object.
* @param {*} fn handler function or context for handler method.
* @param {*} [context] context object for handler method.
*/
once: function (obj, types, fn, context) {
var that = this;
if (util.isObject(types)) {
util.forEachOwnProperties(types, function (handler, type) {
domevent.once(obj, type, handler, fn);
});
return;
}
function onceHandler() {
fn.apply(context || obj, arguments);
that._off(obj, types, onceHandler, context);
}
domevent.on(obj, types, onceHandler, context);
},
/**
* Cancel event bubbling.
* @param {Event} e Event object.
*/
stopPropagation: function (e) {
if (e.stopPropagation) {
e.stopPropagation();
} else {
e.cancelBubble = true;
}
},
/**
* Cancel browser default actions.
* @param {Event} e Event object.
*/
preventDefault: function (e) {
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
},
/**
* Syntatic sugar of stopPropagation and preventDefault
* @param {Event} e Event object.
*/
stop: function (e) {
domevent.preventDefault(e);
domevent.stopPropagation(e);
},
/**
* Stop scroll events.
* @param {HTMLElement} el HTML element to prevent scroll.
*/
disableScrollPropagation: function (el) {
domevent.on(el, 'mousewheel MozMousePixelScroll', domevent.stopPropagation);
},
/**
* Stop all events related with click.
* @param {HTMLElement} el HTML element to prevent all event related with click.
*/
disableClickPropagation: function (el) {
domevent.on(el, DRAG.START.join(' ') + ' click dblclick', domevent.stopPropagation);
},
/**
* Get mouse position from mouse event.
*
* If supplied relatveElement parameter then return relative position based on element.
* @param {Event} mouseEvent Mouse event object
* @param {HTMLElement} relativeElement HTML element that calculate relative position.
* @returns {number[]} mouse position.
*/
getMousePosition: function (mouseEvent, relativeElement) {
var rect;
if (!relativeElement) {
return [mouseEvent.clientX, mouseEvent.clientY];
}
rect = relativeElement.getBoundingClientRect();
return [mouseEvent.clientX - rect.left - relativeElement.clientLeft, mouseEvent.clientY - rect.top - relativeElement.clientTop];
},
/**
* Normalize mouse wheel event that different each browsers.
* @param {MouseEvent} e Mouse wheel event.
* @returns {Number} delta
*/
getWheelDelta: function (e) {
var delta = 0;
if (e.wheelDelta) {
delta = e.wheelDelta / 120;
}
if (e.detail) {
delta = -e.detail / 3;
}
return delta;
},
/**
* prevent firing mouseleave event when mouse entered child elements.
* @param {HTMLElement} el HTML element
* @param {MouseEvent} e Mouse event
* @returns {Boolean} leave?
* @private
*/
_checkMouse: function (el, e) {
var related = e.relatedTarget;
if (!related) {
return true;
}
try {
while (related && related !== el) {
related = related.parentNode;
}
} catch (err) {
return false;
}
return related !== el;
},
/**
* Trigger specific events to html element.
* @param {HTMLElement} obj HTMLElement
* @param {string} type Event type name
* @param {object} [eventData] Event data
*/
trigger: function (obj, type, eventData) {
var rMouseEvent = /(mouse|click)/;
if (util.isUndefined(eventData) && rMouseEvent.exec(type)) {
eventData = domevent.mouseEvent(type);
}
if (obj.dispatchEvent) {
obj.dispatchEvent(eventData);
} else if (obj.fireEvent) {
obj.fireEvent('on' + type, eventData);
}
},
/**
* Create virtual mouse event.
*
* Tested at
*
* - IE7 ~ IE11
* - Chrome
* - Firefox
* - Safari
* @param {string} type Event type
* @param {object} [eventObj] Event data
* @returns {MouseEvent} Virtual mouse event.
*/
mouseEvent: function (type, eventObj) {
var evt, e;
e = util.extend({
bubbles: true,
cancelable: type !== 'mousemove',
view: window,
wheelDelta: 0,
detail: 0,
screenX: 0,
screenY: 0,
clientX: 0,
clientY: 0,
ctrlKey: false,
altKey: false,
shiftKey: false,
metaKey: false,
button: 0,
relatedTarget: undefined // eslint-disable-line
}, eventObj);
// prevent throw error when inserting wheelDelta property to mouse event on below IE8
if (browser.msie && browser.version < 9) {
delete e.wheelDelta;
}
if (typeof document.createEvent === 'function') {
evt = document.createEvent('MouseEvents');
evt.initMouseEvent(type, e.bubbles, e.cancelable, e.view, e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, document.body.parentNode);
} else if (document.createEventObject) {
evt = document.createEventObject();
util.forEach(e, function (value, propName) {
evt[propName] = value;
}, this);
evt.button = {
0: 1,
1: 4,
2: 2
}[evt.button] || evt.button;
}
return evt;
},
/**
* Normalize mouse event's button attributes.
*
* Can detect which button is clicked by this method.
*
* Meaning of return numbers
*
* - 0: primary mouse button
* - 1: wheel button or center button
* - 2: secondary mouse button
* @param {MouseEvent} mouseEvent - The mouse event object want to know.
* @returns {number} - The value of meaning which button is clicked?
*/
getMouseButton: function (mouseEvent) {
var button,
primary = '0,1,3,5,7',
secondary = '2,6',
wheel = '4';
/* istanbul ignore else */
if (document.implementation.hasFeature('MouseEvents', '2.0')) {
return mouseEvent.button;
}
button = mouseEvent.button + '';
if (~primary.indexOf(button)) {
return 0;
} else if (~secondary.indexOf(button)) {
return 2;
} else if (~wheel.indexOf(button)) {
return 1;
}
}
};
module.exports = domevent;
/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
/**
* @fileoverview Common collections.
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
*/
'use strict';
var snippet = __webpack_require__(8);
var util = snippet,
forEachProp = util.forEachOwnProperties,
forEachArr = util.forEachArray,
isFunc = util.isFunction,
isObj = util.isObject;
var aps = Array.prototype.slice;
/**
* Common collection.
*
* It need function for get model's unique id.
*
* if the function is not supplied then it use default function {@link Collection#getItemID}
* @constructor
* @param {function} [getItemIDFn] function for get model's id.
* @ignore
*/
function Collection(getItemIDFn) {
/**
* @type {object.<string, *>}
*/
this.items = {};
/**
* @type {number}
*/
this.length = 0;
if (isFunc(getItemIDFn)) {
/**
* @type {function}
*/
this.getItemID = getItemIDFn;
}
}
/**********
* static props
**********/
/**
* Combind supplied function filters and condition.
* @param {...function} filters - function filters
* @returns {function} combined filter
*/
Collection.and = function (filters) {
var cnt;
filters = aps.call(arguments);
cnt = filters.length;
return function (item) {
var i = 0;
for (; i < cnt; i += 1) {
if (!filters[i].call(null, item)) {
return false;
}
}
return true;
};
};
/**
* Combine multiple function filters with OR clause.
* @param {...function} filters - function filters
* @returns {function} combined filter
*/
Collection.or = function (filters) {
var cnt;
filters = aps.call(arguments);
cnt = filters.length;
return function (item) {
var i = 1,
result = filters[0].call(null, item);
for (; i < cnt; i += 1) {
result = result || filters[i].call(null, item);
}
return result;
};
};
/**
* Merge several collections.
*
* You can\'t merge collections different _getEventID functions. Take case of use.
* @param {...Collection} collections collection arguments to merge
* @returns {Collection} merged collection.
*/
Collection.merge = function (collections) {
// eslint-disable-line
var cols = aps.call(arguments),
newItems = {},
merged = new Collection(cols[0].getItemID),
extend = util.extend;
forEachArr(cols, function (col) {
extend(newItems, col.items);
});
merged.items = newItems;
merged.length = util.keys(merged.items).length;
return merged;
};
/**********
* prototype props
**********/
/**
* get model's unique id.
* @param {object} item model instance.
* @returns {number} model unique id.
*/
Collection.prototype.getItemID = function (item) {
return item._id + '';
};
/**
* add models.
* @param {...*} item models to add this collection.
*/
Collection.prototype.add = function (item) {
var id, ownItems;
if (arguments.length > 1) {
forEachArr(aps.call(arguments), function (o) {
this.add(o);
}, this);
return;
}
id = this.getItemID(item);
ownItems = this.items;
if (!ownItems[id]) {
this.length += 1;
}
ownItems[id] = item;
};
/**
* remove models.
* @param {...(object|string|number)} id model instance or unique id to delete.
* @returns {array} deleted model list.
*/
Collection.prototype.remove = function (id) {
var removed = [],
ownItems,
itemToRemove;
if (!this.length) {
return removed;
}
if (arguments.length > 1) {
removed = util.map(aps.call(arguments), function (id) {
return this.remove(id);
}, this);
return removed;
}
ownItems = this.items;
if (isObj(id)) {
id = this.getItemID(id);
}
if (!ownItems[id]) {
return removed;
}
this.length -= 1;
itemToRemove = ownItems[id];
delete ownItems[id];
return itemToRemove;
};
/**
* remove all models in collection.
*/
Collection.prototype.clear = function () {
this.items = {};
this.length = 0;
};
/**
* check collection has specific model.
* @param {(object|string|number|function)} id model instance or id or filter function to check
* @returns {boolean} is has model?
*/
Collection.prototype.has = function (id) {
var isFilter, has;
if (!this.length) {
return false;
}
isFilter = isFunc(id);
has = false;
if (isFilter) {
this.each(function (item) {
if (id(item) === true) {
has = true;
return false;
}
return true;
});
} else {
id = isObj(id) ? this.getItemID(id) : id;
has = util.isExisty(this.items[id]);
}
return has;
};
/**
* invoke callback when model exist in collection.
* @param {(string|number)} id model unique id.
* @param {function} fn the callback.
* @param {*} [context] callback context.
*/
Collection.prototype.doWhenHas = function (id, fn, context) {
var item = this.items[id];
if (!util.isExisty(item)) {
return;
}
fn.call(context || this, item);
};
/**
* Search model. and return new collection.
* @param {function} filter filter function.
* @returns {Collection} new collection with filtered models.
* @example
* collection.find(function(item) {
* return item.edited === true;
* });
*
* function filter1(item) {
* return item.edited === false;
* }
*
* function filter2(item) {
* return item.disabled === false;
* }
*
* collection.find(Collection.and(filter1, filter2));
*
* collection.find(Collection.or(filter1, filter2));
*/
Collection.prototype.find = function (filter) {
var result = new Collection();
if (this.hasOwnProperty('getItemID')) {
result.getItemID = this.getItemID;
}
this.each(function (item) {
if (filter(item) === true) {
result.add(item);
}
});
return result;
};
/**
* Group element by specific key values.
*
* if key parameter is function then invoke it and use returned value.
* @param {(string|number|function|array)} key key property or getter function. if string[] supplied, create each collection before grouping.
* @param {function} [groupFunc] - function that return each group's key
* @returns {object.<string, Collection>} grouped object
* @example
*
* // pass `string`, `number`, `boolean` type value then group by property value.
* collection.groupBy('gender'); // group by 'gender' property value.
* collection.groupBy(50); // group by '50' property value.
*
* // pass `function` then group by return value. each invocation `function` is called with `(item)`.
* collection.groupBy(function(item) {
* if (item.score > 60) {
* return 'pass';
* }
* return 'fail';
* });
*
* // pass `array` with first arguments then create each collection before grouping.
* collection.groupBy(['go', 'ruby', 'javascript']);
* // result: { 'go': empty Collection, 'ruby': empty Collection, 'javascript': empty Collection }
*
* // can pass `function` with `array` then group each elements.
* collection.groupBy(['go', 'ruby', 'javascript'], function(item) {
* if (item.isFast) {
* return 'go';
* }
*
* return item.name;
* });
*/
Collection.prototype.groupBy = function (key, groupFunc) {
var result = {},
collection,
baseValue,
keyIsFunc = isFunc(key),
getItemIDFn = this.getItemID;
if (util.isArray(key)) {
util.forEachArray(key, function (k) {
result[k + ''] = new Collection(getItemIDFn);
});
if (!groupFunc) {
return result;
}
key = groupFunc;
keyIsFunc = true;
}
this.each(function (item) {
if (keyIsFunc) {
baseValue = key(item);
} else {
baseValue = item[key];
if (isFunc(baseValue)) {
baseValue = baseValue.apply(item);
}
}
collection = result[baseValue];
if (!collection) {
collection = result[baseValue] = new Collection(getItemIDFn);
}
collection.add(item);
});
return result;
};
/**
* Return single item in collection.
*
* Returned item is inserted in this collection firstly.
* @returns {object} item.
*/
Collection.prototype.single = function () {
var result;
this.each(function (item) {
result = item;
return false;
}, this);
return result;
};
/**
* sort a basis of supplied compare function.
* @param {function} compareFunction compareFunction
* @returns {array} sorted array.
*/
Collection.prototype.sort = function (compareFunction) {
var arr = [];
this.each(function (item) {
arr.push(item);
});
if (isFunc(compareFunction)) {
arr = arr.sort(compareFunction);
}
return arr;
};
/**
* iterate each model element.
*
* when iteratee return false then break the loop.
* @param {function} iteratee iteratee(item, index, items)
* @param {*} [context] context
*/
Collection.prototype.each = function (iteratee, context) {
forEachProp(this.items, iteratee, context || this);
};
/**
* return new array with collection items.
* @returns {array} new array.
*/
Collection.prototype.toArray = function () {
if (!this.length) {
return [];
}
return util.map(this.items, function (item) {
return item;
});
};
module.exports = Collection;
/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {
/**
* @fileoverview The base class of views.
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
*/
'use strict';
var util = __webpack_require__(8);
var domutil = __webpack_require__(7);
var Collection = __webpack_require__(10);
/**
* Base class of views.
*
* All views create own container element inside supplied container element.
* @constructor
* @param {options} options The object for describe view's specs.
* @param {HTMLElement} container Default container element for view. you can use this element for this.container syntax.
* @ignore
*/
function View(options, container) {
var id = util.stamp(this);
options = options || {};
if (util.isUndefined(container)) {
container = domutil.appendHTMLElement('div');
}
domutil.addClass(container, 'tui-view-' + id);
/**
* unique id
* @type {number}
*/
this.id = id;
/**
* base element of view.
* @type {HTMLDIVElement}
*/
this.container = container;
/**
* child views.
* @type {Collection}
*/
this.childs = new Collection(function (view) {
return util.stamp(view);
});
/**
* parent view instance.
* @type {View}
*/
this.parent = null;
}
/**
* Add child views.
* @param {View} view The view instance to add.
* @param {function} [fn] Function for invoke before add. parent view class is supplied first arguments.
*/
View.prototype.addChild = function (view, fn) {
if (fn) {
fn.call(view, this);
}
// add parent view
view.parent = this;
this.childs.add(view);
};
/**
* Remove added child view.
* @param {(number|View)} id View id or instance itself to remove.
* @param {function} [fn] Function for invoke before remove. parent view class is supplied first arguments.
*/
View.prototype.removeChild = function (id, fn) {
var view = util.isNumber(id) ? this.childs.items[id] : id;
id = util.stamp(view);
if (fn) {
fn.call(view, this);
}
this.childs.remove(id);
};
/**
* Render view recursively.
*/
View.prototype.render = function () {
this.childs.each(function (childView) {
childView.render();
});
};
/**
* Invoke function recursively.
* @param {function} fn - function to invoke child view recursively
* @param {boolean} [skipThis=false] - set true then skip invoke with this(root) view.
*/
View.prototype.recursive = function (fn, skipThis) {
if (!util.isFunction(fn)) {
return;
}
if (!skipThis) {
fn(this);
}
this.childs.each(function (childView) {
childView.recursive(fn);
});
};
/**
* Resize view recursively to parent.
*/
View.prototype.resize = function () {
var args = Array.prototype.slice.call(arguments),
parent = this.parent;
while (parent) {
if (util.isFunction(parent._onResize)) {
parent._onResize.apply(parent, args);
}
parent = parent.parent;
}
};
/**
* Invoking method before destroying.
*/
View.prototype._beforeDestroy = function () {};
/**
* Clear properties
*/
View.prototype._destroy = function () {
this._beforeDestroy();
this.childs.clear();
this.container.innerHTML = '';
this.id = this.parent = this.childs = this.container = null;
};
/**
* Destroy child view recursively.
* @param {boolean} isChildView - Whether it is the child view or not
*/
View.prototype.destroy = function (isChildView) {
this.childs.each(function (childView) {
childView.destroy(true);
childView._destroy();
});
if (isChildView) {
return;
}
this._destroy();
};
/**
* Calculate view's container element bound.
* @returns {object} The bound of container element.
*/
View.prototype.getViewBound = function () {
var container = this.container,
position = domutil.getPosition(container),
size = domutil.getSize(container);
return {
x: position[0],
y: position[1],
width: size[0],
height: size[1]
};
};
module.exports = View;
/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {/**
* @fileoverview General drag handler
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
*/
'use strict';
var util = __webpack_require__(8);
var domutil = __webpack_require__(7);
var domevent = __webpack_require__(9);
/**
* @constructor
* @mixes CustomEvents
* @param {object} options - options for drag handler
* @param {number} [options.distance=10] - distance in pixels after mouse must move before dragging should start
* @param {HTMLElement} container - container element to bind drag events
* @ignore
*/
function Drag(options, container) {
domevent.on(container, 'mousedown', this._onMouseDown, this);
this.options = util.extend({
distance: 10
}, options);
/**
* @type {HTMLElement}
*/
this.container = container;
/**
* @type {boolean}
*/
this._isMoved = false;
/**
* dragging distance in pixel between mousedown and firing dragStart events
* @type {number}
*/
this._distance = 0;
/**
* @type {boolean}
*/
this._dragStartFired = false;
/**
* @type {object}
*/
this._dragStartEventData = null;
}
/**
* Destroy method.
*/
Drag.prototype.destroy = function () {
domevent.off(this.container, 'mousedown', this._onMouseDown, this);
this.options = this.container = this._isMoved = this._distance = this._dragStartFired = this._dragStartEventData = null;
};
/**
* Toggle events for mouse dragging.
* @param {boolean} toBind - bind events related with dragging when supplied "true"
*/
Drag.prototype._toggleDragEvent = function (toBind) {
var container = this.container,
domMethod,
method;
if (toBind) {
domMethod = 'on';
method = 'disable';
} else {
domMethod = 'off';
method = 'enable';
}
domutil[method + 'TextSelection'](container);
domutil[method + 'ImageDrag'](container);
domevent[domMethod](global.document, {
mousemove: this._onMouseMove,
mouseup: this._onMouseUp
}, this);
};
/**
* Normalize mouse event object.
* @param {MouseEvent} mouseEvent - mouse event object.
* @returns {object} normalized mouse event data.
*/
Drag.prototype._getEventData = function (mouseEvent) {
return {
target: mouseEvent.target || mouseEvent.srcElement,
originEvent: mouseEvent
};
};
/**
* MouseDown DOM event handler.
* @param {MouseEvent} mouseDownEvent MouseDown event object.
*/
Drag.prototype._onMouseDown = function (mouseDownEvent) {
// only primary button can start drag.
if (domevent.getMouseButton(mouseDownEvent) !== 0) {
return;
}
this._distance = 0;
this._dragStartFired = false;
this._dragStartEventData = this._getEventData(mouseDownEvent);
this._toggleDragEvent(true);
};
/**
* MouseMove DOM event handler.
* @emits Drag#drag
* @emits Drag#dragStart
* @param {MouseEvent} mouseMoveEvent MouseMove event object.
*/
Drag.prototype._onMouseMove = function (mouseMoveEvent) {
var distance = this.options.distance;
// prevent automatic scrolling.
domevent.preventDefault(mouseMoveEvent);
this._isMoved = true;
if (this._distance < distance) {
this._distance += 1;
return;
}
if (!this._dragStartFired) {
this._dragStartFired = true;
/**
* Drag starts events. cancelable.
* @event Drag#dragStart
* @type {object}
* @property {HTMLElement} target - target element in this event.
* @property {MouseEvent} originEvent - original mouse event object.
*/
if (!this.invoke('dragStart', this._dragStartEventData)) {
this._toggleDragEvent(false);
return;
}
}
/**
* Events while dragging.
* @event Drag#drag
* @type {object}
* @property {HTMLElement} target - target element in this event.
* @property {MouseEvent} originEvent - original mouse event object.
*/
this.fire('drag', this._getEventData(mouseMoveEvent));
};
/**
* MouseUp DOM event handler.
* @param {MouseEvent} mouseUpEvent MouseUp event object.
* @emits Drag#dragEnd
* @emits Drag#click
*/
Drag.prototype._onMouseUp = function (mouseUpEvent) {
this._toggleDragEvent(false);
// emit "click" event when not emitted drag event between mousedown and mouseup.
if (this._isMoved) {
this._isMoved = false;
/**
* Drag end events.
* @event Drag#dragEnd
* @type {MouseEvent}
* @property {HTMLElement} target - target element in this event.
* @property {MouseEvent} originEvent - original mouse event object.
*/
this.fire('dragEnd', this._getEventData(mouseUpEvent));
return;
}
/**
* Click events.
* @event Drag#click
* @type {MouseEvent}
* @property {HTMLElement} target - target element in this event.
* @property {MouseEvent} originEvent - original mouse event object.
*/
this.fire('click', this._getEventData(mouseUpEvent));
};
util.CustomEvents.mixin(Drag);
module.exports = Drag;
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ }),
/* 13 */
/***/ (function(module, exports, __webpack_require__) {
/**
* @fileoverview ColorPicker factory module
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
*/
'use strict';
var util = __webpack_require__(8);
var colorutil = __webpack_require__(14);
var Layout = __webpack_require__(15);
var Palette = __webpack_require__(16);
var Slider = __webpack_require__(18);
var hostnameSent = false;
/**
* send hostname
* @ignore
*/
function sendHostname() {
var hostname = location.hostname;
if (hostnameSent) {
return;
}
hostnameSent = true;
util.imagePing('https://www.google-analytics.com/collect', {
v: 1,
t: 'event',
tid: 'UA-115377265-9',
cid: hostname,
dp: hostname,
dh: 'color-picker'
});
}
/**
* @constructor
* @mixes CustomEvents
* @param {object} options - options for colorpicker component
* @param {HTMLDivElement} options.container - container element
* @param {string} [options.color='#ffffff'] - default selected color
* @param {string[]} [options.preset] - color preset for palette (use base16 palette if not supplied)
* @param {string} [options.cssPrefix='tui-colorpicker-'] - css prefix text for each child elements
* @param {string} [options.detailTxt='Detail'] - text for detail button.
* @param {boolean} [options.usageStatistics=true] - Let us know the hostname. If you don't want to send the hostname, please set to false.
* @example
* var colorPicker = tui.colorPicker; // or require('tui-color-picker')
*
* colorPicker.create({
* container: document.getElementById('color-picker')
* });
*/
function ColorPicker(options) {
var layout;
if (!(this instanceof ColorPicker)) {
return new ColorPicker(options);
}
/**
* Option object
* @type {object}
* @private
*/
options = this.options = util.extend({
container: null,
color: '#f8f8f8',
preset: ['#181818', '#282828', '#383838', '#585858', '#b8b8b8', '#d8d8d8', '#e8e8e8', '#f8f8f8', '#ab4642', '#dc9656', '#f7ca88', '#a1b56c', '#86c1b9', '#7cafc2', '#ba8baf', '#a16946'],
cssPrefix: 'tui-colorpicker-',
detailTxt: 'Detail',
usageStatistics: true
}, options);
if (!options.container) {
throw new Error('ColorPicker(): need container option.');
}
/**********
* Create layout view
**********/
/**
* @type {Layout}
* @private
*/
layout = this.layout = new Layout(options, options.container);
/**********
* Create palette view
**********/
this.palette = new Palette(options, layout.container);
this.palette.on({
'_selectColor': this._onSelectColorInPalette,
'_toggleSlider': this._onToggleSlider
}, this);
/**********
* Create slider view
**********/
this.slider = new Slider(options, layout.container);
this.slider.on('_selectColor', this._onSelectColorInSlider, this);
/**********
* Add child views
**********/
layout.addChild(this.palette);
layout.addChild(this.slider);
this.render(options.color);
if (options.usageStatistics) {
sendHostname();
}
}
/**
* Handler method for Palette#_selectColor event
* @private
* @fires ColorPicker#selectColor
* @param {object} selectColorEventData - event data
*/
ColorPicker.prototype._onSelectColorInPalette = function (selectColorEventData) {
var color = selectColorEventData.color,
opt = this.options;
if (!colorutil.isValidRGB(color) && color !== '') {
this.render();
return;
}
/**
* @event ColorPicker#selectColor
* @type {object}
* @property {string} color - selected color (hex string)
* @property {string} origin - flags for represent the source of event fires.
*/
this.fire('selectColor', {
color: color,
origin: 'palette'
});
if (opt.color === color) {
return;
}
opt.color = color;
this.render(color);
};
/**
* Handler method for Palette#_toggleSlider event
* @private
*/
ColorPicker.prototype._onToggleSlider = function () {
this.slider.toggle(!this.slider.isVisible());
};
/**
* Handler method for Slider#_selectColor event
* @private
* @fires ColorPicker#selectColor
* @param {object} selectColorEventData - event data
*/
ColorPicker.prototype._onSelectColorInSlider = function (selectColorEventData) {
var color = selectColorEventData.color,
opt = this.options;
/**
* @event ColorPicker#selectColor
* @type {object}
* @property {string} color - selected color (hex string)
* @property {string} origin - flags for represent the source of event fires.
* @ignore
*/
this.fire('selectColor', {
color: color,
origin: 'slider'
});
if (opt.color === color) {
return;
}
opt.color = color;
this.palette.render(color);
};
/**********
* PUBLIC API
**********/
/**
* Set color to colorpicker instance.<br>
* The string parameter must be hex color value
* @param {string} hexStr - hex formatted color string
* @example
* colorPicker.setColor('#ffff00');
*/
ColorPicker.prototype.setColor = function (hexStr) {
if (!colorutil.isValidRGB(hexStr)) {
throw new Error('ColorPicker#setColor(): need valid hex string color value');
}
this.options.color = hexStr;
this.render(hexStr);
};
/**
* Get hex color string of current selected color in colorpicker instance.
* @returns {string} hex string formatted color
* @example
* colorPicker.setColor('#ffff00');
* colorPicker.getColor(); // '#ffff00';
*/
ColorPicker.prototype.getColor = function () {
return this.options.color;
};
/**
* Toggle colorpicker element. set true then reveal colorpicker view.
* @param {boolean} [isShow=false] - A flag to show
* @example
* colorPicker.toggle(false); // hide
* colorPicker.toggle(); // hide
* colorPicker.toggle(true); // show
*/
ColorPicker.prototype.toggle = function (isShow) {
this.layout.container.style.display = !!isShow ? 'block' : 'none';
};
/**
* Render colorpicker
* @param {string} [color] - selected color
* @ignore
*/
ColorPicker.prototype.render = function (color) {
this.layout.render(color || this.options.color);
};
/**
* Destroy colorpicker instance.
* @example
* colorPicker.destroy(); // DOM-element is removed
*/
ColorPicker.prototype.destroy = function () {
this.layout.destroy();
this.options.container.innerHTML = '';
this.layout = this.slider = this.palette = this.options = null;
};
util.CustomEvents.mixin(ColorPicker);
module.exports = ColorPicker;
/***/ }),
/* 14 */
/***/ (function(module, exports) {
/**
* @fileoverview Utility methods to manipulate colors
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
*/
'use strict';
var hexRX = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i;
var colorutil = {
/**
* pad left zero characters.
* @param {number} number number value to pad zero.
* @param {number} length pad length to want.
* @returns {string} padded string.
*/
leadingZero: function (number, length) {
var zero = '',
i = 0;
if ((number + '').length > length) {
return number + '';
}
for (; i < length - 1; i += 1) {
zero += '0';
}
return (zero + number).slice(length * -1);
},
/**
* Check validate of hex string value is RGB
* @param {string} str - rgb hex string
* @returns {boolean} return true when supplied str is valid RGB hex string
*/
isValidRGB: function (str) {
return hexRX.test(str);
},
// @license RGB <-> HSV conversion utilities based off of http://www.cs.rit.edu/~ncs/color/t_convert.html
/**
* Convert color hex string to rgb number array
* @param {string} hexStr - hex string
* @returns {number[]} rgb numbers
*/
hexToRGB: function (hexStr) {
var r, g, b;
if (!colorutil.isValidRGB(hexStr)) {
return false;
}
hexStr = hexStr.substring(1);
r = parseInt(hexStr.substr(0, 2), 16);
g = parseInt(hexStr.substr(2, 2), 16);
b = parseInt(hexStr.substr(4, 2), 16);
return [r, g, b];
},
/**
* Convert rgb number to hex string
* @param {number} r - red
* @param {number} g - green
* @param {number} b - blue
* @returns {string|boolean} return false when supplied rgb number is not valid. otherwise, converted hex string
*/
rgbToHEX: function (r, g, b) {
var hexStr = '#' + colorutil.leadingZero(r.toString(16), 2) + colorutil.leadingZero(g.toString(16), 2) + colorutil.leadingZero(b.toString(16), 2);
if (colorutil.isValidRGB(hexStr)) {
return hexStr;
}
return false;
},
/**
* Convert rgb number to HSV value
* @param {number} r - red
* @param {number} g - green
* @param {number} b - blue
* @returns {number[]} hsv value
*/
rgbToHSV: function (r, g, b) {
var max, min, h, s, v, d;
r /= 255;
g /= 255;
b /= 255;
max = Math.max(r, g, b);
min = Math.min(r, g, b);
v = max;
d = max - min;
s = max === 0 ? 0 : d / max;
if (max === min) {
h = 0;
} else {
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);break;
case g:
h = (b - r) / d + 2;break;
case b:
h = (r - g) / d + 4;break;
// no default
}
h /= 6;
}
return [Math.round(h * 360), Math.round(s * 100), Math.round(v * 100)];
},
/**
* Convert HSV number to RGB
* @param {number} h - hue
* @param {number} s - saturation
* @param {number} v - value
* @returns {number[]} rgb value
*/
hsvToRGB: function (h, s, v) {
var r, g, b;
var i;
var f, p, q, t;
h = Math.max(0, Math.min(360, h));
s = Math.max(0, Math.min(100, s));
v = Math.max(0, Math.min(100, v));
s /= 100;
v /= 100;
if (s === 0) {
// Achromatic (grey)
r = g = b = v;
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
h /= 60; // sector 0 to 5
i = Math.floor(h);
f = h - i; // factorial part of h
p = v * (1 - s);
q = v * (1 - s * f);
t = v * (1 - s * (1 - f));
switch (i) {
case 0:
r = v;g = t;b = p;break;
case 1:
r = q;g = v;b = p;break;
case 2:
r = p;g = v;b = t;break;
case 3:
r = p;g = q;b = v;break;
case 4:
r = t;g = p;b = v;break;
default:
r = v;g = p;b = q;break;
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
};
module.exports = colorutil;
/***/ }),
/* 15 */
/***/ (function(module, exports, __webpack_require__) {
/**
* @fileoverview ColorPicker layout module
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
*/
'use strict';
var util = __webpack_require__(8);
var domutil = __webpack_require__(7);
var View = __webpack_require__(11);
/**
* @constructor
* @extends {View}
* @param {object} options - option object
* @param {string} options.cssPrefix - css prefix for each child elements
* @param {HTMLDivElement} container - container
* @ignore
*/
function Layout(options, container) {
/**
* option object
* @type {object}
*/
this.options = util.extend({
cssPrefix: 'tui-colorpicker-'
}, options);
container = domutil.appendHTMLElement('div', container, this.options.cssPrefix + 'container');
View.call(this, options, container);
this.render();
}
util.inherit(Layout, View);
/**
* @override
* @param {string} [color] - selected color
*/
Layout.prototype.render = function (color) {
this.recursive(function (view) {
view.render(color);
}, true);
};
module.exports = Layout;
/***/ }),
/* 16 */
/***/ (function(module, exports, __webpack_require__) {
/**
* @fileoverview Color palette view
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
*/
'use strict';
var util = __webpack_require__(8);
var domutil = __webpack_require__(7);
var colorutil = __webpack_require__(14);
var domevent = __webpack_require__(9);
var View = __webpack_require__(11);
var tmpl = __webpack_require__(17);
/**
* @constructor
* @extends {View}
* @mixes CustomEvents
* @param {object} options - options for color palette view
* @param {string[]} options.preset - color list
* @param {HTMLDivElement} container - container element
* @ignore
*/
function Palette(options, container) {
/**
* option object
* @type {object}
*/
this.options = util.extend({
cssPrefix: 'tui-colorpicker-',
preset: ['#181818', '#282828', '#383838', '#585858', '#B8B8B8', '#D8D8D8', '#E8E8E8', '#F8F8F8', '#AB4642', '#DC9656', '#F7CA88', '#A1B56C', '#86C1B9', '#7CAFC2', '#BA8BAF', '#A16946'],
detailTxt: 'Detail'
}, options);
container = domutil.appendHTMLElement('div', container, this.options.cssPrefix + 'palette-container');
View.call(this, options, container);
}
util.inherit(Palette, View);
/**
* Mouse click event handler
* @fires Palette#_selectColor
* @fires Palette#_toggleSlider
* @param {MouseEvent} clickEvent - mouse event object
*/
Palette.prototype._onClick = function (clickEvent) {
var options = this.options,
target = clickEvent.srcElement || clickEvent.target,
eventData = {};
if (domutil.hasClass(target, options.cssPrefix + 'palette-button')) {
eventData.color = target.value;
/**
* @event Palette#_selectColor
* @type {object}
* @property {string} color - selected color value
*/
this.fire('_selectColor', eventData);
return;
}
if (domutil.hasClass(target, options.cssPrefix + 'palette-toggle-slider')) {
/**
* @event Palette#_toggleSlider
*/
this.fire('_toggleSlider');
}
};
/**
* Textbox change event handler
* @fires Palette#_selectColor
* @param {Event} changeEvent - change event object
*/
Palette.prototype._onChange = function (changeEvent) {
var options = this.options,
target = changeEvent.srcElement || changeEvent.target,
eventData = {};
if (domutil.hasClass(target, options.cssPrefix + 'palette-hex')) {
eventData.color = target.value;
/**
* @event Palette#_selectColor
* @type {object}
* @property {string} color - selected color value
*/
this.fire('_selectColor', eventData);
}
};
/**
* Invoke before destory
* @override
*/
Palette.prototype._beforeDestroy = function () {
this._toggleEvent(false);
};
/**
* Toggle view DOM events
* @param {boolean} [onOff=false] - true to bind event.
*/
Palette.prototype._toggleEvent = function (onOff) {
var options = this.options,
container = this.container,
method = domevent[!!onOff ? 'on' : 'off'],
hexTextBox;
method(container, 'click', this._onClick, this);
hexTextBox = domutil.find('.' + options.cssPrefix + 'palette-hex', container);
if (hexTextBox) {
method(hexTextBox, 'change', this._onChange, this);
}
};
/**
* Render palette
* @override
*/
Palette.prototype.render = function (color) {
var options = this.options,
html = '';
this._toggleEvent(false);
html = tmpl.layout.replace('{{colorList}}', util.map(options.preset, function (itemColor) {
var itemHtml = '';
var style = '';
if (colorutil.isValidRGB(itemColor)) {
style = domutil.applyTemplate(tmpl.itemStyle, { color: itemColor });
}
itemHtml = domutil.applyTemplate(tmpl.item, {
itemStyle: style,
itemClass: !itemColor ? ' ' + options.cssPrefix + 'color-transparent' : '',
color: itemColor,
cssPrefix: options.cssPrefix,
selected: itemColor === color ? ' ' + options.cssPrefix + 'selected' : ''
});
return itemHtml;
}).join(''));
html = domutil.applyTemplate(html, {
cssPrefix: options.cssPrefix,
detailTxt: options.detailTxt,
color: color
});
this.container.innerHTML = html;
this._toggleEvent(true);
};
util.CustomEvents.mixin(Palette);
module.exports = Palette;
/***/ }),
/* 17 */
/***/ (function(module, exports) {
/**
* @fileoverview Palette view template
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
*/
'use strict';
var layout = ['<ul class="{{cssPrefix}}clearfix">{{colorList}}</ul>', '<div class="{{cssPrefix}}clearfix" style="overflow:hidden">', '<input type="button" class="{{cssPrefix}}palette-toggle-slider" value="{{detailTxt}}" />', '<input type="text" class="{{cssPrefix}}palette-hex" value="{{color}}" maxlength="7" />', '<span class="{{cssPrefix}}palette-preview" style="background-color:{{color}};color:{{color}}">{{color}}</span>', '</div>'].join('\n');
var item = '<li><input class="{{cssPrefix}}palette-button{{selected}}{{itemClass}}" type="button" style="{{itemStyle}}" title="{{color}}" value="{{color}}" /></li>';
var itemStyle = 'background-color:{{color}};color:{{color}}';
module.exports = {
layout: layout,
item: item,
itemStyle: itemStyle
};
/***/ }),
/* 18 */
/***/ (function(module, exports, __webpack_require__) {
/**
* @fileoverview Slider view
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
*/
'use strict';
var util = __webpack_require__(8);
var domutil = __webpack_require__(7);
var domevent = __webpack_require__(9);
var svgvml = __webpack_require__(19);
var colorutil = __webpack_require__(14);
var View = __webpack_require__(11);
var Drag = __webpack_require__(12);
var tmpl = __webpack_require__(20);
// Limitation position of point element inside of colorslider and hue bar
// Minimum value can to be negative because that using color point of handle element is center point. not left, top point.
var COLORSLIDER_POS_LIMIT_RANGE = [-7, 112];
var HUEBAR_POS_LIMIT_RANGE = [-3, 115];
var HUE_WHEEL_MAX = 359.99;
/**
* @constructor
* @extends {View}
* @mixes CustomEvents
* @param {object} options - options for view
* @param {string} options.cssPrefix - design css prefix
* @param {HTMLElement} container - container element
* @ignore
*/
function Slider(options, container) {
container = domutil.appendHTMLElement('div', container, options.cssPrefix + 'slider-container');
container.style.display = 'none';
View.call(this, options, container);
/**
* @type {object}
*/
this.options = util.extend({
color: '#f8f8f8',
cssPrefix: 'tui-colorpicker-'
}, options);
/**
* Cache immutable data in click, drag events.
*
* (i.e. is event related with colorslider? or huebar?)
* @type {object}
* @property {boolean} isColorSlider
* @property {number[]} containerSize
*/
this._dragDataCache = {};
/**
* Color slider handle element
* @type {SVG|VML}
*/
this.sliderHandleElement = null;
/**
* hue bar handle element
* @type {SVG|VML}
*/
this.huebarHandleElement = null;
/**
* Element that render base color in colorslider part
* @type {SVG|VML}
*/
this.baseColorElement = null;
/**
* @type {Drag}
*/
this.drag = new Drag({
distance: 0
}, container);
// bind drag events
this.drag.on({
'dragStart': this._onDragStart,
'drag': this._onDrag,
'dragEnd': this._onDragEnd,
'click': this._onClick
}, this);
}
util.inherit(Slider, View);
/**
* @override
*/
Slider.prototype._beforeDestroy = function () {
this.drag.off();
this.drag = this.options = this._dragDataCache = this.sliderHandleElement = this.huebarHandleElement = this.baseColorElement = null;
};
/**
* Toggle slider view
* @param {boolean} onOff - set true then reveal slider view
*/
Slider.prototype.toggle = function (onOff) {
this.container.style.display = !!onOff ? 'block' : 'none';
};
/**
* Get slider display status
* @returns {boolean} return true when slider is visible
*/
Slider.prototype.isVisible = function () {
return this.container.style.display === 'block';
};
/**
* Render slider view
* @override
* @param {string} colorStr - hex string color from parent view (Layout)
*/
Slider.prototype.render = function (colorStr) {
var that = this,
container = that.container,
options = that.options,
html = tmpl.layout,
rgb,
hsv;
if (!colorutil.isValidRGB(colorStr)) {
return;
}
html = html.replace(/{{slider}}/, tmpl.slider);
html = html.replace(/{{huebar}}/, tmpl.huebar);
html = html.replace(/{{cssPrefix}}/g, options.cssPrefix);
that.container.innerHTML = html;
that.sliderHandleElement = domutil.find('.' + options.cssPrefix + 'slider-handle', container);
that.huebarHandleElement = domutil.find('.' + options.cssPrefix + 'huebar-handle', container);
that.baseColorElement = domutil.find('.' + options.cssPrefix + 'slider-basecolor', container);
rgb = colorutil.hexToRGB(colorStr);
hsv = colorutil.rgbToHSV.apply(null, rgb);
this.moveHue(hsv[0], true);
this.moveSaturationAndValue(hsv[1], hsv[2], true);
};
/**
* Move colorslider by newLeft(X), newTop(Y) value
* @private
* @param {number} newLeft - left pixel value to move handle
* @param {number} newTop - top pixel value to move handle
* @param {boolean} [silent=false] - set true then not fire custom event
*/
Slider.prototype._moveColorSliderHandle = function (newLeft, newTop, silent) {
var handle = this.sliderHandleElement,
handleColor;
// Check position limitation.
newTop = Math.max(COLORSLIDER_POS_LIMIT_RANGE[0], newTop);
newTop = Math.min(COLORSLIDER_POS_LIMIT_RANGE[1], newTop);
newLeft = Math.max(COLORSLIDER_POS_LIMIT_RANGE[0], newLeft);
newLeft = Math.min(COLORSLIDER_POS_LIMIT_RANGE[1], newLeft);
svgvml.setTranslateXY(handle, newLeft, newTop);
handleColor = newTop > 50 ? 'white' : 'black';
svgvml.setStrokeColor(handle, handleColor);
if (!silent) {
this.fire('_selectColor', {
color: colorutil.rgbToHEX.apply(null, this.getRGB())
});
}
};
/**
* Move colorslider by supplied saturation and values.
*
* The movement of color slider handle follow HSV cylinder model. {@link https://en.wikipedia.org/wiki/HSL_and_HSV}
* @param {number} saturation - the percent of saturation (0% ~ 100%)
* @param {number} value - the percent of saturation (0% ~ 100%)
* @param {boolean} [silent=false] - set true then not fire custom event
*/
Slider.prototype.moveSaturationAndValue = function (saturation, value, silent) {
var absMin, maxValue, newLeft, newTop;
saturation = saturation || 0;
value = value || 0;
absMin = Math.abs(COLORSLIDER_POS_LIMIT_RANGE[0]);
maxValue = COLORSLIDER_POS_LIMIT_RANGE[1];
// subtract absMin value because current color position is not left, top of handle element.
// The saturation. from left 0 to right 100
newLeft = saturation * maxValue / 100 - absMin;
// The Value. from top 100 to bottom 0. that why newTop subtract by maxValue.
newTop = maxValue - value * maxValue / 100 - absMin;
this._moveColorSliderHandle(newLeft, newTop, silent);
};
/**
* Move color slider handle to supplied position
*
* The number of X, Y must be related value from color slider container
* @private
* @param {number} x - the pixel value to move handle
* @param {number} y - the pixel value to move handle
*/
Slider.prototype._moveColorSliderByPosition = function (x, y) {
var offset = COLORSLIDER_POS_LIMIT_RANGE[0];
this._moveColorSliderHandle(x + offset, y + offset);
};
/**
* Get saturation and value value.
* @returns {number[]} saturation and value
*/
Slider.prototype.getSaturationAndValue = function () {
var absMin = Math.abs(COLORSLIDER_POS_LIMIT_RANGE[0]),
maxValue = absMin + COLORSLIDER_POS_LIMIT_RANGE[1],
position = svgvml.getTranslateXY(this.sliderHandleElement),
saturation,
value;
saturation = (position[1] + absMin) / maxValue * 100;
// The value of HSV color model is inverted. top 100 ~ bottom 0. so subtract by 100
value = 100 - (position[0] + absMin) / maxValue * 100;
return [saturation, value];
};
/**
* Move hue handle supplied pixel value
* @private
* @param {number} newTop - pixel to move hue handle
* @param {boolean} [silent=false] - set true then not fire custom event
*/
Slider.prototype._moveHueHandle = function (newTop, silent) {
var hueHandleElement = this.huebarHandleElement,
baseColorElement = this.baseColorElement,
newGradientColor,
hexStr;
newTop = Math.max(HUEBAR_POS_LIMIT_RANGE[0], newTop);
newTop = Math.min(HUEBAR_POS_LIMIT_RANGE[1], newTop);
svgvml.setTranslateY(hueHandleElement, newTop);
newGradientColor = colorutil.hsvToRGB(this.getHue(), 100, 100);
hexStr = colorutil.rgbToHEX.apply(null, newGradientColor);
svgvml.setGradientColorStop(baseColorElement, hexStr);
if (!silent) {
this.fire('_selectColor', {
color: colorutil.rgbToHEX.apply(null, this.getRGB())
});
}
};
/**
* Move hue bar handle by supplied degree
* @param {number} degree - (0 ~ 359.9 degree)
* @param {boolean} [silent=false] - set true then not fire custom event
*/
Slider.prototype.moveHue = function (degree, silent) {
var newTop = 0,
absMin,
maxValue;
absMin = Math.abs(HUEBAR_POS_LIMIT_RANGE[0]);
maxValue = absMin + HUEBAR_POS_LIMIT_RANGE[1];
degree = degree || 0;
newTop = maxValue * degree / HUE_WHEEL_MAX - absMin;
this._moveHueHandle(newTop, silent);
};
/**
* Move hue bar handle by supplied percent
* @private
* @param {number} y - pixel value to move hue handle
*/
Slider.prototype._moveHueByPosition = function (y) {
var offset = HUEBAR_POS_LIMIT_RANGE[0];
this._moveHueHandle(y + offset);
};
/**
* Get huebar handle position by color degree
* @returns {number} degree (0 ~ 359.9 degree)
*/
Slider.prototype.getHue = function () {
var handle = this.huebarHandleElement,
position = svgvml.getTranslateXY(handle),
absMin,
maxValue;
absMin = Math.abs(HUEBAR_POS_LIMIT_RANGE[0]);
maxValue = absMin + HUEBAR_POS_LIMIT_RANGE[1];
// maxValue : 359.99 = pos.y : x
return (position[0] + absMin) * HUE_WHEEL_MAX / maxValue;
};
/**
* Get HSV value from slider
* @returns {number[]} hsv values
*/
Slider.prototype.getHSV = function () {
var sv = this.getSaturationAndValue(),
h = this.getHue();
return [h].concat(sv);
};
/**
* Get RGB value from slider
* @returns {number[]} RGB value
*/
Slider.prototype.getRGB = function () {
return colorutil.hsvToRGB.apply(null, this.getHSV());
};
/**********
* Drag event handler
**********/
/**
* Cache immutable data when dragging or click view
* @param {object} event - Click, DragStart event.
* @returns {object} cached data.
*/
Slider.prototype._prepareColorSliderForMouseEvent = function (event) {
var options = this.options,
sliderPart = domutil.closest(event.target, '.' + options.cssPrefix + 'slider-part'),
cache;
cache = this._dragDataCache = {
isColorSlider: domutil.hasClass(sliderPart, options.cssPrefix + 'slider-left'),
parentElement: sliderPart
};
return cache;
};
/**
* Click event handler
* @param {object} clickEvent - Click event from Drag module
*/
Slider.prototype._onClick = function (clickEvent) {
var cache = this._prepareColorSliderForMouseEvent(clickEvent),
mousePos = domevent.getMousePosition(clickEvent.originEvent, cache.parentElement);
if (cache.isColorSlider) {
this._moveColorSliderByPosition(mousePos[0], mousePos[1]);
} else {
this._moveHueByPosition(mousePos[1]);
}
this._dragDataCache = null;
};
/**
* DragStart event handler
* @param {object} dragStartEvent - dragStart event data from Drag#dragStart
*/
Slider.prototype._onDragStart = function (dragStartEvent) {
this._prepareColorSliderForMouseEvent(dragStartEvent);
};
/**
* Drag event handler
* @param {Drag#drag} dragEvent - drag event data
*/
Slider.prototype._onDrag = function (dragEvent) {
var cache = this._dragDataCache,
mousePos = domevent.getMousePosition(dragEvent.originEvent, cache.parentElement);
if (cache.isColorSlider) {
this._moveColorSliderByPosition(mousePos[0], mousePos[1]);
} else {
this._moveHueByPosition(mousePos[1]);
}
};
/**
* Drag#dragEnd event handler
*/
Slider.prototype._onDragEnd = function () {
this._dragDataCache = null;
};
util.CustomEvents.mixin(Slider);
module.exports = Slider;
/***/ }),
/* 19 */
/***/ (function(module, exports, __webpack_require__) {
/**
* @fileoverview module for manipulate SVG or VML object
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
*/
'use strict';
var util = __webpack_require__(8);
var PARSE_TRANSLATE_NUM_REGEX = /[\.\-0-9]+/g;
var SVG_HUE_HANDLE_RIGHT_POS = -6;
/* istanbul ignore next */
var svgvml = {
/**
* Return true when browser is below IE8.
* @returns {boolean} is old browser?
*/
isOldBrowser: function () {
var _isOldBrowser = svgvml._isOldBrowser;
if (!util.isExisty(_isOldBrowser)) {
svgvml._isOldBrowser = _isOldBrowser = util.browser.msie && util.browser.version < 9;
}
return _isOldBrowser;
},
/**
* Get translate transform value
* @param {SVG|VML} obj - svg or vml object that want to know translate x, y
* @returns {number[]} translated coordinates [x, y]
*/
getTranslateXY: function (obj) {
var temp;
if (svgvml.isOldBrowser()) {
temp = obj.style;
return [parseFloat(temp.top), parseFloat(temp.left)];
}
temp = obj.getAttribute('transform');
if (!temp) {
return [0, 0];
}
temp = temp.match(PARSE_TRANSLATE_NUM_REGEX);
// need caution for difference of VML, SVG coordinates system.
// translate command need X coords in first parameter. but VML is use CSS coordinate system(top, left)
return [parseFloat(temp[1]), parseFloat(temp[0])];
},
/**
* Set translate transform value
* @param {SVG|VML} obj - SVG or VML object to setting translate transform.
* @param {number} x - translate X value
* @param {number} y - translate Y value
*/
setTranslateXY: function (obj, x, y) {
if (svgvml.isOldBrowser()) {
obj.style.left = x + 'px';
obj.style.top = y + 'px';
} else {
obj.setAttribute('transform', 'translate(' + x + ',' + y + ')');
}
},
/**
* Set translate only Y value
* @param {SVG|VML} obj - SVG or VML object to setting translate transform.
* @param {number} y - translate Y value
*/
setTranslateY: function (obj, y) {
if (svgvml.isOldBrowser()) {
obj.style.top = y + 'px';
} else {
obj.setAttribute('transform', 'translate(' + SVG_HUE_HANDLE_RIGHT_POS + ',' + y + ')');
}
},
/**
* Set stroke color to SVG or VML object
* @param {SVG|VML} obj - SVG or VML object to setting stroke color
* @param {string} colorStr - color string
*/
setStrokeColor: function (obj, colorStr) {
if (svgvml.isOldBrowser()) {
obj.strokecolor = colorStr;
} else {
obj.setAttribute('stroke', colorStr);
}
},
/**
* Set gradient stop color to SVG, VML object.
* @param {SVG|VML} obj - SVG, VML object to applying gradient stop color
* @param {string} colorStr - color string
*/
setGradientColorStop: function (obj, colorStr) {
if (svgvml.isOldBrowser()) {
obj.color = colorStr;
} else {
obj.setAttribute('stop-color', colorStr);
}
}
};
module.exports = svgvml;
/***/ }),
/* 20 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {/**
* @fileoverview Slider template
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
*/
'use strict';
var util = __webpack_require__(8);
var layout = ['<div class="{{cssPrefix}}slider-left {{cssPrefix}}slider-part">{{slider}}</div>', '<div class="{{cssPrefix}}slider-right {{cssPrefix}}slider-part">{{huebar}}</div>'].join('\n');
var SVGSlider = ['<svg class="{{cssPrefix}}svg {{cssPrefix}}svg-slider">', '<defs>', '<linearGradient id="{{cssPrefix}}svg-fill-color" x1="0%" y1="0%" x2="100%" y2="0%">', '<stop offset="0%" stop-color="rgb(255,255,255)" />', '<stop class="{{cssPrefix}}slider-basecolor" offset="100%" stop-color="rgb(255,0,0)" />', '</linearGradient>', '<linearGradient id="{{cssPrefix}}svn-fill-black" x1="0%" y1="0%" x2="0%" y2="100%">', '<stop offset="0%" style="stop-color:rgb(0,0,0);stop-opacity:0" />', '<stop offset="100%" style="stop-color:rgb(0,0,0);stop-opacity:1" />', '</linearGradient>', '</defs>', '<rect width="100%" height="100%" fill="url(#{{cssPrefix}}svg-fill-color)"></rect>', '<rect width="100%" height="100%" fill="url(#{{cssPrefix}}svn-fill-black)"></rect>', '<path transform="translate(0,0)" class="{{cssPrefix}}slider-handle" d="M0 7.5 L15 7.5 M7.5 15 L7.5 0 M2 7 a5.5 5.5 0 1 1 0 1 Z" stroke="black" stroke-width="0.75" fill="none" />', '</svg>'].join('\n');
var VMLSlider = ['<div class="{{cssPrefix}}vml-slider">', '<v:rect strokecolor="none" class="{{cssPrefix}}vml {{cssPrefix}}vml-slider-bg">', '<v:fill class="{{cssPrefix}}vml {{cssPrefix}}slider-basecolor" type="gradient" method="none" color="#ff0000" color2="#fff" angle="90" />', '</v:rect>', '<v:rect strokecolor="#ccc" class="{{cssPrefix}}vml {{cssPrefix}}vml-slider-bg">', '<v:fill type="gradient" method="none" color="black" color2="white" o:opacity2="0%" class="{{cssPrefix}}vml" />', '</v:rect>', '<v:shape class="{{cssPrefix}}vml {{cssPrefix}}slider-handle" coordsize="1 1" style="width:1px;height:1px;"' + 'path="m 0,7 l 14,7 m 7,14 l 7,0 ar 12,12 2,2 z" filled="false" stroked="true" />', '</div>'].join('\n');
var SVGHuebar = ['<svg class="{{cssPrefix}}svg {{cssPrefix}}svg-huebar">', '<defs>', '<linearGradient id="g" x1="0%" y1="0%" x2="0%" y2="100%">', '<stop offset="0%" stop-color="rgb(255,0,0)" />', '<stop offset="16.666%" stop-color="rgb(255,255,0)" />', '<stop offset="33.333%" stop-color="rgb(0,255,0)" />', '<stop offset="50%" stop-color="rgb(0,255,255)" />', '<stop offset="66.666%" stop-color="rgb(0,0,255)" />', '<stop offset="83.333%" stop-color="rgb(255,0,255)" />', '<stop offset="100%" stop-color="rgb(255,0,0)" />', '</linearGradient>', '</defs>', '<rect width="18px" height="100%" fill="url(#g)"></rect>', '<path transform="translate(-6,-3)" class="{{cssPrefix}}huebar-handle" d="M0 0 L4 4 L0 8 L0 0 Z" fill="black" stroke="none" />', '</svg>'].join('\n');
var VMLHuebar = ['<div class="{{cssPrefix}}vml-huebar">', '<v:rect strokecolor="#ccc" class="{{cssPrefix}}vml {{cssPrefix}}vml-huebar-bg">', '<v:fill type="gradient" method="none" colors="' + '0% rgb(255,0,0), 16.666% rgb(255,255,0), 33.333% rgb(0,255,0), 50% rgb(0,255,255), 66.666% rgb(0,0,255), 83.333% rgb(255,0,255), 100% rgb(255,0,0)' + '" angle="180" class="{{cssPrefix}}vml" />', '</v:rect>', '<v:shape class="{{cssPrefix}}vml {{cssPrefix}}huebar-handle" coordsize="1 1" style="width:1px;height:1px;position:absolute;z-index:1;right:22px;top:-3px;"' + 'path="m 0,0 l 4,4 l 0,8 l 0,0 z" filled="true" fillcolor="black" stroked="false" />', '</div>'].join('\n');
var isOldBrowser = util.browser.msie && util.browser.version < 9;
if (isOldBrowser) {
global.document.namespaces.add('v', 'urn:schemas-microsoft-com:vml');
}
module.exports = {
layout: layout,
slider: isOldBrowser ? VMLSlider : SVGSlider,
huebar: isOldBrowser ? VMLHuebar : SVGHuebar
};
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ })
/******/ ])
});
;
/***/ }),
/* 83 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _tuiCodeSnippet = __webpack_require__(3);
var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet);
var _util = __webpack_require__(72);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* Range control class
* @class
* @ignore
*/
var Range = function () {
function Range(rangeElement) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, Range);
this._value = options.value || 0;
this.rangeElement = rangeElement;
this._drawRangeElement();
this.rangeWidth = (0, _util.toInteger)(window.getComputedStyle(rangeElement, null).width) - 12;
this._min = options.min || 0;
this._max = options.max || 100;
this._absMax = this._min * -1 + this._max;
this.realTimeEvent = options.realTimeEvent || false;
this._addClickEvent();
this._addDragEvent();
this.value = options.value;
this.trigger('change');
}
/**
* Set range max value and re position cursor
* @param {number} maxValue - max value
*/
_createClass(Range, [{
key: 'trigger',
/**
* event tirigger
* @param {string} type - type
*/
value: function trigger(type) {
this.fire(type, this._value);
}
/**
* Make range element
* @private
*/
}, {
key: '_drawRangeElement',
value: function _drawRangeElement() {
this.rangeElement.classList.add('tui-image-editor-range');
this.bar = document.createElement('div');
this.bar.className = 'tui-image-editor-virtual-range-bar';
this.subbar = document.createElement('div');
this.subbar.className = 'tui-image-editor-virtual-range-subbar';
this.pointer = document.createElement('div');
this.pointer.className = 'tui-image-editor-virtual-range-pointer';
this.bar.appendChild(this.subbar);
this.bar.appendChild(this.pointer);
this.rangeElement.appendChild(this.bar);
}
/**
* Add Range click event
* @private
*/
}, {
key: '_addClickEvent',
value: function _addClickEvent() {
var _this = this;
this.rangeElement.addEventListener('click', function (event) {
event.stopPropagation();
if (event.target.className !== 'tui-image-editor-range') {
return;
}
var touchPx = event.offsetX;
var ratio = touchPx / _this.rangeWidth;
var value = _this._absMax * ratio + _this._min;
_this.pointer.style.left = ratio * _this.rangeWidth + 'px';
_this.subbar.style.right = (1 - ratio) * _this.rangeWidth + 'px';
_this._value = value;
_this.fire('change', value);
});
}
/**
* Add Range drag event
* @private
*/
}, {
key: '_addDragEvent',
value: function _addDragEvent() {
var _this2 = this;
this.pointer.addEventListener('mousedown', function (event) {
_this2.firstPosition = event.screenX;
_this2.firstLeft = (0, _util.toInteger)(_this2.pointer.style.left) || 0;
_this2.dragEventHandler = {
changeAngle: _this2._changeAngle.bind(_this2),
stopChangingAngle: _this2._stopChangingAngle.bind(_this2)
};
document.addEventListener('mousemove', _this2.dragEventHandler.changeAngle);
document.addEventListener('mouseup', _this2.dragEventHandler.stopChangingAngle);
});
}
/**
* change angle event
* @param {object} event - change event
* @private
*/
}, {
key: '_changeAngle',
value: function _changeAngle(event) {
var changePosition = event.screenX;
var diffPosition = changePosition - this.firstPosition;
var touchPx = this.firstLeft + diffPosition;
touchPx = touchPx > this.rangeWidth ? this.rangeWidth : touchPx;
touchPx = touchPx < 0 ? 0 : touchPx;
this.pointer.style.left = touchPx + 'px';
this.subbar.style.right = this.rangeWidth - touchPx + 'px';
var ratio = touchPx / this.rangeWidth;
var value = this._absMax * ratio + this._min;
this._value = value;
if (this.realTimeEvent) {
this.fire('change', value);
}
}
/**
* stop change angle event
* @private
*/
}, {
key: '_stopChangingAngle',
value: function _stopChangingAngle() {
this.fire('change', this._value);
document.removeEventListener('mousemove', this.dragEventHandler.changeAngle);
document.removeEventListener('mouseup', this.dragEventHandler.stopChangingAngle);
}
}, {
key: 'max',
set: function set(maxValue) {
this._max = maxValue;
this._absMax = this._min * -1 + this._max;
this.value = this._value;
},
get: function get() {
return this._max;
}
/**
* Get range value
* @returns {Number} range value
*/
}, {
key: 'value',
get: function get() {
return this._value;
}
/**
* Set range value
* @param {Number} value range value
* @param {Boolean} fire whether fire custom event or not
*/
,
set: function set(value) {
var absValue = value - this._min;
var leftPosition = absValue * this.rangeWidth / this._absMax;
if (this.rangeWidth < leftPosition) {
leftPosition = this.rangeWidth;
}
this.pointer.style.left = leftPosition + 'px';
this.subbar.style.right = this.rangeWidth - leftPosition + 'px';
this._value = value;
}
}]);
return Range;
}();
_tuiCodeSnippet2.default.CustomEvents.mixin(Range);
exports.default = Range;
/***/ }),
/* 84 */
/***/ (function(module, exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* Submenu Base Class
* @class
* @ignore
*/
var Submenu = function () {
function Submenu(subMenuElement, _ref) {
var name = _ref.name,
iconStyle = _ref.iconStyle,
menuBarPosition = _ref.menuBarPosition,
templateHtml = _ref.templateHtml;
_classCallCheck(this, Submenu);
this.selector = function (str) {
return subMenuElement.querySelector(str);
};
this.menuBarPosition = menuBarPosition;
this.toggleDirection = menuBarPosition === 'top' ? 'down' : 'up';
this.colorPickerControls = [];
this._makeSubMenuElement(subMenuElement, {
name: name,
iconStyle: iconStyle,
templateHtml: templateHtml
});
}
_createClass(Submenu, [{
key: 'colorPickerChangeShow',
value: function colorPickerChangeShow(occurredControl) {
this.colorPickerControls.forEach(function (pickerControl) {
if (occurredControl !== pickerControl) {
pickerControl.hide();
}
});
}
/**
* Get butten type
* @param {HTMLElement} button - event target element
* @param {array} buttonNames - Array of button names
* @returns {string} - button type
*/
}, {
key: 'getButtonType',
value: function getButtonType(button, buttonNames) {
return button.className.match(RegExp('(' + buttonNames.join('|') + ')'))[0];
}
/**
* Get butten type
* @param {HTMLElement} target - event target element
* @param {string} removeClass - remove class name
* @param {string} addClass - add class name
*/
}, {
key: 'changeClass',
value: function changeClass(target, removeClass, addClass) {
target.classList.remove(removeClass);
target.classList.add(addClass);
}
/**
* Interface method whose implementation is optional.
* Returns the menu to its default state.
*/
}, {
key: 'changeStandbyMode',
value: function changeStandbyMode() {}
/**
* Interface method whose implementation is optional.
* Executed when the menu starts.
*/
}, {
key: 'changeStartMode',
value: function changeStartMode() {}
/**
* Make submenu dom element
* @param {HTMLElement} subMenuElement - subment dom element
* @param {Object} iconStyle - icon style
* @private
*/
}, {
key: '_makeSubMenuElement',
value: function _makeSubMenuElement(subMenuElement, _ref2) {
var name = _ref2.name,
iconStyle = _ref2.iconStyle,
templateHtml = _ref2.templateHtml;
var iconSubMenu = document.createElement('div');
iconSubMenu.className = 'tui-image-editor-menu-' + name;
iconSubMenu.innerHTML = templateHtml({ iconStyle: iconStyle });
subMenuElement.appendChild(iconSubMenu);
}
}]);
return Submenu;
}();
exports.default = Submenu;
/***/ }),
/* 85 */
/***/ (function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (_ref) {
var _ref$iconStyle = _ref.iconStyle,
normal = _ref$iconStyle.normal,
active = _ref$iconStyle.active;
return "\n <ul class=\"tui-image-editor-submenu-item\">\n <li id=\"tie-shape-button\">\n <div class=\"tui-image-editor-button rect\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-shape-rectangle\"\n class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-shape-rectangle\"\n class=\"active\"/>\n </svg>\n </div>\n <label> Rectangle </label>\n </div>\n <div class=\"tui-image-editor-button circle\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-shape-circle\"\n class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-shape-circle\"\n class=\"active\"/>\n </svg>\n </div>\n <label> Circle </label>\n </div>\n <div class=\"tui-image-editor-button triangle\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-shape-triangle\"\n class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-shape-triangle\"\n class=\"active\"/>\n </svg>\n </div>\n <label> Triangle </label>\n </div>\n </li>\n <li class=\"tui-image-editor-partition\">\n <div></div>\n </li>\n <li id=\"tie-shape-color-button\">\n <div id=\"tie-color-fill\" title=\"Fill\"></div>\n <div id=\"tie-color-stroke\" title=\"Stroke\"></div>\n </li>\n <li class=\"tui-image-editor-partition only-left-right\">\n <div></div>\n </li>\n <li class=\"tui-image-editor-newline tui-image-editor-range-wrap\">\n <label class=\"range\">Stroke</label>\n <div id=\"tie-stroke-range\"></div>\n <input id=\"tie-stroke-range-value\" class=\"tui-image-editor-range-value\" value=\"0\" />\n </li>\n </ul>\n";
};
/***/ }),
/* 86 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _submenuBase = __webpack_require__(84);
var _submenuBase2 = _interopRequireDefault(_submenuBase);
var _crop = __webpack_require__(87);
var _crop2 = _interopRequireDefault(_crop);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/**
* Crop ui class
* @class
* @ignore
*/
var Crop = function (_Submenu) {
_inherits(Crop, _Submenu);
function Crop(subMenuElement, _ref) {
var iconStyle = _ref.iconStyle,
menuBarPosition = _ref.menuBarPosition;
_classCallCheck(this, Crop);
var _this = _possibleConstructorReturn(this, (Crop.__proto__ || Object.getPrototypeOf(Crop)).call(this, subMenuElement, {
name: 'crop',
iconStyle: iconStyle,
menuBarPosition: menuBarPosition,
templateHtml: _crop2.default
}));
_this.status = 'active';
_this._els = {
apply: _this.selector('#tie-crop-button .apply'),
cancel: _this.selector('#tie-crop-button .cancel')
};
return _this;
}
/**
* Add event for crop
* @param {Object} actions - actions for crop
* @param {Function} actions.crop - crop action
* @param {Function} actions.cancel - cancel action
*/
_createClass(Crop, [{
key: 'addEvent',
value: function addEvent(actions) {
var _this2 = this;
this.actions = actions;
this._els.apply.addEventListener('click', function () {
_this2.actions.crop();
_this2._els.apply.classList.remove('active');
});
this._els.cancel.addEventListener('click', function () {
_this2.actions.cancel();
_this2._els.apply.classList.remove('active');
});
}
/**
* Executed when the menu starts.
*/
}, {
key: 'changeStartMode',
value: function changeStartMode() {
this.actions.modeChange('crop');
}
/**
* Returns the menu to its default state.
*/
}, {
key: 'changeStandbyMode',
value: function changeStandbyMode() {
this.actions.stopDrawingMode();
}
/**
* Change apply button status
* @param {Boolean} enableStatus - apply button status
*/
}, {
key: 'changeApplyButtonStatus',
value: function changeApplyButtonStatus(enableStatus) {
if (enableStatus) {
this._els.apply.classList.add('active');
} else {
this._els.apply.classList.remove('active');
}
}
}]);
return Crop;
}(_submenuBase2.default);
exports.default = Crop;
/***/ }),
/* 87 */
/***/ (function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (_ref) {
var _ref$iconStyle = _ref.iconStyle,
normal = _ref$iconStyle.normal,
active = _ref$iconStyle.active;
return "\n <ul class=\"tui-image-editor-submenu-item\">\n <li id=\"tie-crop-button\" class=\"apply\">\n <div class=\"tui-image-editor-button apply\">\n <svg class=\"svg_ic-menu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-apply\" class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-apply\" class=\"active\"/>\n </svg>\n <label>\n Apply\n </label>\n </div>\n <div class=\"tui-image-editor-button cancel\">\n <svg class=\"svg_ic-menu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-cancel\" class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-cancel\" class=\"active\"/>\n </svg>\n <label>\n Cancel\n </label>\n </div>\n </li>\n </ul>\n";
};
/***/ }),
/* 88 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _tuiCodeSnippet = __webpack_require__(3);
var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet);
var _submenuBase = __webpack_require__(84);
var _submenuBase2 = _interopRequireDefault(_submenuBase);
var _flip = __webpack_require__(89);
var _flip2 = _interopRequireDefault(_flip);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/**
* Flip ui class
* @class
* @ignore
*/
var Flip = function (_Submenu) {
_inherits(Flip, _Submenu);
function Flip(subMenuElement, _ref) {
var iconStyle = _ref.iconStyle,
menuBarPosition = _ref.menuBarPosition;
_classCallCheck(this, Flip);
var _this = _possibleConstructorReturn(this, (Flip.__proto__ || Object.getPrototypeOf(Flip)).call(this, subMenuElement, {
name: 'flip',
iconStyle: iconStyle,
menuBarPosition: menuBarPosition,
templateHtml: _flip2.default
}));
_this.flipStatus = false;
_this._els = {
flipButton: _this.selector('#tie-flip-button')
};
return _this;
}
/**
* Add event for flip
* @param {Object} actions - actions for flip
* @param {Function} actions.flip - flip action
*/
_createClass(Flip, [{
key: 'addEvent',
value: function addEvent(actions) {
this._actions = actions;
this._els.flipButton.addEventListener('click', this._changeFlip.bind(this));
}
/**
* change Flip status
* @param {object} event - change event
* @private
*/
}, {
key: '_changeFlip',
value: function _changeFlip(event) {
var _this2 = this;
var button = event.target.closest('.tui-image-editor-button');
if (button) {
var flipType = this.getButtonType(button, ['flipX', 'flipY', 'resetFlip']);
if (!this.flipStatus && flipType === 'resetFlip') {
return;
}
this._actions.flip(flipType).then(function (flipStatus) {
var flipClassList = _this2._els.flipButton.classList;
_this2.flipStatus = false;
flipClassList.remove('resetFlip');
_tuiCodeSnippet2.default.forEach(['flipX', 'flipY'], function (type) {
flipClassList.remove(type);
if (flipStatus[type]) {
flipClassList.add(type);
flipClassList.add('resetFlip');
_this2.flipStatus = true;
}
});
});
}
}
}]);
return Flip;
}(_submenuBase2.default);
exports.default = Flip;
/***/ }),
/* 89 */
/***/ (function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (_ref) {
var _ref$iconStyle = _ref.iconStyle,
normal = _ref$iconStyle.normal,
active = _ref$iconStyle.active;
return "\n <ul id=\"tie-flip-button\" class=\"tui-image-editor-submenu-item\">\n <li>\n <div class=\"tui-image-editor-button flipX\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-flip-x\" class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-flip-x\" class=\"active\"/>\n </svg>\n </div>\n <label>\n Flip X\n </label>\n </div>\n <div class=\"tui-image-editor-button flipY\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-flip-y\" class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-flip-y\" class=\"active\"/>\n </svg>\n </div>\n <label>\n Flip Y\n </label>\n </div>\n </li>\n <li class=\"tui-image-editor-partition\">\n <div></div>\n </li>\n <li>\n <div class=\"tui-image-editor-button resetFlip\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-flip-reset\"\n class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-flip-reset\"\n class=\"active\"/>\n </svg>\n </div>\n <label>\n Reset\n </label>\n </div>\n </li>\n </ul>\n";
};
/***/ }),
/* 90 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _range = __webpack_require__(83);
var _range2 = _interopRequireDefault(_range);
var _submenuBase = __webpack_require__(84);
var _submenuBase2 = _interopRequireDefault(_submenuBase);
var _rotate = __webpack_require__(91);
var _rotate2 = _interopRequireDefault(_rotate);
var _util = __webpack_require__(72);
var _consts = __webpack_require__(73);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var CLOCKWISE = 30;
var COUNTERCLOCKWISE = -30;
/**
* Rotate ui class
* @class
* @ignore
*/
var Rotate = function (_Submenu) {
_inherits(Rotate, _Submenu);
function Rotate(subMenuElement, _ref) {
var iconStyle = _ref.iconStyle,
menuBarPosition = _ref.menuBarPosition;
_classCallCheck(this, Rotate);
var _this = _possibleConstructorReturn(this, (Rotate.__proto__ || Object.getPrototypeOf(Rotate)).call(this, subMenuElement, {
name: 'rotate',
iconStyle: iconStyle,
menuBarPosition: menuBarPosition,
templateHtml: _rotate2.default
}));
_this._els = {
rotateButton: _this.selector('#tie-retate-button'),
rotateRange: new _range2.default(_this.selector('#tie-rotate-range'), _consts.defaultRotateRangeValus),
rotateRangeValue: _this.selector('#tie-ratate-range-value')
};
return _this;
}
/**
* Add event for rotate
* @param {Object} actions - actions for crop
* @param {Function} actions.rotate - rotate action
* @param {Function} actions.setAngle - set angle action
*/
_createClass(Rotate, [{
key: 'addEvent',
value: function addEvent(actions) {
// {rotate, setAngle}
this.actions = actions;
this._els.rotateButton.addEventListener('click', this._changeRotateForButton.bind(this));
this._els.rotateRange.on('change', this._changeRotateForRange.bind(this));
this._els.rotateRangeValue.setAttribute('readonly', true);
}
/**
* Change rotate for range
* @param {number} value - angle value
* @private
*/
}, {
key: '_changeRotateForRange',
value: function _changeRotateForRange(value) {
var angle = (0, _util.toInteger)(value);
this._els.rotateRangeValue.value = angle;
this.actions.setAngle(angle);
}
/**
* Change rotate for button
* @param {object} event - add button event object
* @private
*/
}, {
key: '_changeRotateForButton',
value: function _changeRotateForButton(event) {
var button = event.target.closest('.tui-image-editor-button');
if (button) {
var rotateType = this.getButtonType(button, ['counterclockwise', 'clockwise']);
var rotateAngle = {
clockwise: CLOCKWISE,
counterclockwise: COUNTERCLOCKWISE
}[rotateType];
this.actions.rotate(rotateAngle);
}
}
}]);
return Rotate;
}(_submenuBase2.default);
exports.default = Rotate;
/***/ }),
/* 91 */
/***/ (function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (_ref) {
var _ref$iconStyle = _ref.iconStyle,
normal = _ref$iconStyle.normal,
active = _ref$iconStyle.active;
return "\n <ul class=\"tui-image-editor-submenu-item\">\n <li id=\"tie-retate-button\">\n <div class=\"tui-image-editor-button clockwise\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-rotate-clockwise\"\n class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-rotate-clockwise\"\n class=\"active\"/>\n </svg>\n </div>\n <label> 30 </label>\n </div>\n <div class=\"tui-image-editor-button counterclockwise\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-rotate-counterclockwise\"\n class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-rotate-counterclockwise\"\n class=\"active\"/>\n </svg>\n </div>\n <label> -30 </label>\n </div>\n </li>\n <li class=\"tui-image-editor-partition only-left-right\">\n <div></div>\n </li>\n <li class=\"tui-image-editor-newline tui-image-editor-range-wrap\">\n <label class=\"range\">Range</label>\n <div id=\"tie-rotate-range\"></div>\n <input id=\"tie-ratate-range-value\" class=\"tui-image-editor-range-value\" value=\"0\" />\n </li>\n </ul>\n";
};
/***/ }),
/* 92 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _range = __webpack_require__(83);
var _range2 = _interopRequireDefault(_range);
var _colorpicker = __webpack_require__(81);
var _colorpicker2 = _interopRequireDefault(_colorpicker);
var _submenuBase = __webpack_require__(84);
var _submenuBase2 = _interopRequireDefault(_submenuBase);
var _text = __webpack_require__(93);
var _text2 = _interopRequireDefault(_text);
var _util = __webpack_require__(72);
var _consts = __webpack_require__(73);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/**
* Crop ui class
* @class
* @ignore
*/
var Text = function (_Submenu) {
_inherits(Text, _Submenu);
function Text(subMenuElement, _ref) {
var iconStyle = _ref.iconStyle,
menuBarPosition = _ref.menuBarPosition;
_classCallCheck(this, Text);
var _this = _possibleConstructorReturn(this, (Text.__proto__ || Object.getPrototypeOf(Text)).call(this, subMenuElement, {
name: 'text',
iconStyle: iconStyle,
menuBarPosition: menuBarPosition,
templateHtml: _text2.default
}));
_this.effect = {
bold: false,
italic: false,
underline: false
};
_this.align = 'left';
_this._els = {
textEffectButton: _this.selector('#tie-text-effect-button'),
textAlignButton: _this.selector('#tie-text-align-button'),
textColorpicker: new _colorpicker2.default(_this.selector('#tie-text-color'), '#ffbb3b', _this.toggleDirection),
textRange: new _range2.default(_this.selector('#tie-text-range'), _consts.defaultTextRangeValus),
textRangeValue: _this.selector('#tie-text-range-value')
};
return _this;
}
/**
* Add event for text
* @param {Object} actions - actions for text
* @param {Function} actions.changeTextStyle - change text style
*/
_createClass(Text, [{
key: 'addEvent',
value: function addEvent(actions) {
this.actions = actions;
this._els.textEffectButton.addEventListener('click', this._setTextEffectHandler.bind(this));
this._els.textAlignButton.addEventListener('click', this._setTextAlignHandler.bind(this));
this._els.textRange.on('change', this._changeTextRnageHandler.bind(this));
this._els.textRangeValue.value = this._els.textRange.value;
this._els.textRangeValue.setAttribute('readonly', true);
this._els.textColorpicker.on('change', this._changeColorHandler.bind(this));
}
/**
* Returns the menu to its default state.
*/
}, {
key: 'changeStandbyMode',
value: function changeStandbyMode() {
this.actions.stopDrawingMode();
}
/**
* Executed when the menu starts.
*/
}, {
key: 'changeStartMode',
value: function changeStartMode() {
this.actions.modeChange('text');
}
/**
* Get text color
* @returns {string} - text color
*/
}, {
key: '_setTextEffectHandler',
/**
* text effect set handler
* @param {object} event - add button event object
* @private
*/
value: function _setTextEffectHandler(event) {
var button = event.target.closest('.tui-image-editor-button');
var _button$className$mat = button.className.match(/(bold|italic|underline)/),
styleType = _button$className$mat[0];
var styleObj = {
'bold': { fontWeight: 'bold' },
'italic': { fontStyle: 'italic' },
'underline': { textDecoration: 'underline' }
}[styleType];
this.effect[styleType] = !this.effect[styleType];
button.classList.toggle('active');
this.actions.changeTextStyle(styleObj);
}
/**
* text effect set handler
* @param {object} event - add button event object
* @private
*/
}, {
key: '_setTextAlignHandler',
value: function _setTextAlignHandler(event) {
var button = event.target.closest('.tui-image-editor-button');
if (button) {
var styleType = this.getButtonType(button, ['left', 'center', 'right']);
event.currentTarget.classList.remove(this.align);
if (this.align !== styleType) {
event.currentTarget.classList.add(styleType);
}
this.actions.changeTextStyle({ textAlign: styleType });
this.align = styleType;
}
}
/**
* text align set handler
* @param {number} value - range value
* @private
*/
}, {
key: '_changeTextRnageHandler',
value: function _changeTextRnageHandler(value) {
value = (0, _util.toInteger)(value);
if ((0, _util.toInteger)(this._els.textRangeValue.value) !== value) {
this.actions.changeTextStyle({
fontSize: value
});
this._els.textRangeValue.value = value;
}
}
/**
* change color handler
* @param {string} color - change color string
* @private
*/
}, {
key: '_changeColorHandler',
value: function _changeColorHandler(color) {
color = color || 'transparent';
this.actions.changeTextStyle({
'fill': color
});
}
}, {
key: 'textColor',
get: function get() {
return this._els.textColorpicker.color;
}
/**
* Get text size
* @returns {string} - text size
*/
}, {
key: 'fontSize',
get: function get() {
return this._els.textRange.value;
}
/**
* Set text size
* @param {Number} value - text size
*/
,
set: function set(value) {
this._els.textRange.value = value;
this._els.textRangeValue.value = value;
}
}]);
return Text;
}(_submenuBase2.default);
exports.default = Text;
/***/ }),
/* 93 */
/***/ (function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (_ref) {
var _ref$iconStyle = _ref.iconStyle,
normal = _ref$iconStyle.normal,
active = _ref$iconStyle.active;
return "\n <ul class=\"tui-image-editor-submenu-item\">\n <li id=\"tie-text-effect-button\">\n <div class=\"tui-image-editor-button bold\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-text-bold\" class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-text-bold\" class=\"active\"/>\n </svg>\n </div>\n <label> Bold </label>\n </div>\n <div class=\"tui-image-editor-button italic\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-text-italic\" class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-text-italic\" class=\"active\"/>\n </svg>\n </div>\n <label> Italic </label>\n </div>\n <div class=\"tui-image-editor-button underline\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-text-underline\"\n class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-text-underline\"\n class=\"active\"/>\n </svg>\n </div>\n <label> Underline </label>\n </div>\n </li>\n <li class=\"tui-image-editor-partition\">\n <div></div>\n </li>\n <li id=\"tie-text-align-button\">\n <div class=\"tui-image-editor-button left\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-text-align-left\"\n class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-text-align-left\"\n class=\"active\"/>\n </svg>\n </div>\n <label> Left </label>\n </div>\n <div class=\"tui-image-editor-button center\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-text-align-center\"\n class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-text-align-center\"\n class=\"active\"/>\n </svg>\n </div>\n <label> Center </label>\n </div>\n <div class=\"tui-image-editor-button right\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-text-align-right\"\n class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-text-align-right\"\n class=\"active\"/>\n </svg>\n </div>\n <label> Right </label>\n </div>\n </li>\n <li class=\"tui-image-editor-partition\">\n <div></div>\n </li>\n <li>\n <div id=\"tie-text-color\" title=\"Color\"></div>\n </li>\n <li class=\"tui-image-editor-partition only-left-right\">\n <div></div>\n </li>\n <li class=\"tui-image-editor-newline tui-image-editor-range-wrap\">\n <label class=\"range\">Text size</label>\n <div id=\"tie-text-range\"></div>\n <input id=\"tie-text-range-value\" class=\"tui-image-editor-range-value\" value=\"0\" />\n </li>\n </ul>\n";
};
/***/ }),
/* 94 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _submenuBase = __webpack_require__(84);
var _submenuBase2 = _interopRequireDefault(_submenuBase);
var _util = __webpack_require__(72);
var _util2 = _interopRequireDefault(_util);
var _mask = __webpack_require__(95);
var _mask2 = _interopRequireDefault(_mask);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/**
* Mask ui class
* @class
* @ignore
*/
var Mask = function (_Submenu) {
_inherits(Mask, _Submenu);
function Mask(subMenuElement, _ref) {
var iconStyle = _ref.iconStyle,
menuBarPosition = _ref.menuBarPosition;
_classCallCheck(this, Mask);
var _this = _possibleConstructorReturn(this, (Mask.__proto__ || Object.getPrototypeOf(Mask)).call(this, subMenuElement, {
name: 'mask',
iconStyle: iconStyle,
menuBarPosition: menuBarPosition,
templateHtml: _mask2.default
}));
_this._els = {
applyButton: _this.selector('#tie-mask-apply'),
maskImageButton: _this.selector('#tie-mask-image-file')
};
return _this;
}
/**
* Add event for mask
* @param {Object} actions - actions for crop
* @param {Function} actions.loadImageFromURL - load image action
* @param {Function} actions.applyFilter - apply filter action
*/
_createClass(Mask, [{
key: 'addEvent',
value: function addEvent(actions) {
this.actions = actions;
this._els.maskImageButton.addEventListener('change', this._loadMaskFile.bind(this));
this._els.applyButton.addEventListener('click', this._applyMask.bind(this));
}
/**
* Apply mask
* @private
*/
}, {
key: '_applyMask',
value: function _applyMask() {
this.actions.applyFilter();
this._els.applyButton.classList.remove('active');
}
/**
* Load mask file
* @param {object} event - File change event object
* @private
*/
}, {
key: '_loadMaskFile',
value: function _loadMaskFile(event) {
var imgUrl = void 0;
if (!_util2.default.isSupportFileApi()) {
alert('This browser does not support file-api');
}
var _event$target$files = event.target.files,
file = _event$target$files[0];
if (file) {
imgUrl = URL.createObjectURL(file);
this.actions.loadImageFromURL(imgUrl, file);
this._els.applyButton.classList.add('active');
}
}
}]);
return Mask;
}(_submenuBase2.default);
exports.default = Mask;
/***/ }),
/* 95 */
/***/ (function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (_ref) {
var _ref$iconStyle = _ref.iconStyle,
normal = _ref$iconStyle.normal,
active = _ref$iconStyle.active;
return "\n <ul class=\"tui-image-editor-submenu-item\">\n <li>\n <div class=\"tui-image-editor-button\">\n <div>\n <input type=\"file\" accept=\"image/*\" id=\"tie-mask-image-file\">\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-mask-load\" class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-mask-load\" class=\"active\"/>\n </svg>\n </div>\n <label> Load Mask Image </label>\n </div>\n </li>\n <li class=\"tui-image-editor-partition only-left-right\">\n <div></div>\n </li>\n <li id=\"tie-mask-apply\" class=\"tui-image-editor-newline apply\" style=\"margin-top: 22px;margin-bottom: 5px\">\n <div class=\"tui-image-editor-button apply\">\n <svg class=\"svg_ic-menu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-apply\" class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-apply\" class=\"active\"/>\n </svg>\n <label>\n Apply\n </label>\n </div>\n </li>\n </ul>\n";
};
/***/ }),
/* 96 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _tuiCodeSnippet = __webpack_require__(3);
var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet);
var _colorpicker = __webpack_require__(81);
var _colorpicker2 = _interopRequireDefault(_colorpicker);
var _submenuBase = __webpack_require__(84);
var _submenuBase2 = _interopRequireDefault(_submenuBase);
var _icon = __webpack_require__(97);
var _icon2 = _interopRequireDefault(_icon);
var _util = __webpack_require__(72);
var _consts = __webpack_require__(73);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/**
* Icon ui class
* @class
* @ignore
*/
var Icon = function (_Submenu) {
_inherits(Icon, _Submenu);
function Icon(subMenuElement, _ref) {
var iconStyle = _ref.iconStyle,
menuBarPosition = _ref.menuBarPosition;
_classCallCheck(this, Icon);
var _this = _possibleConstructorReturn(this, (Icon.__proto__ || Object.getPrototypeOf(Icon)).call(this, subMenuElement, {
name: 'icon',
iconStyle: iconStyle,
menuBarPosition: menuBarPosition,
templateHtml: _icon2.default
}));
_this.iconType = null;
_this._iconMap = {};
_this._els = {
registIconButton: _this.selector('#tie-icon-image-file'),
addIconButton: _this.selector('#tie-icon-add-button'),
iconColorpicker: new _colorpicker2.default(_this.selector('#tie-icon-color'), '#ffbb3b', _this.toggleDirection)
};
return _this;
}
/**
* Add event for icon
* @param {Object} actions - actions for icon
* @param {Function} actions.registCustomIcon - register icon
* @param {Function} actions.addIcon - add icon
* @param {Function} actions.changeColor - change icon color
*/
_createClass(Icon, [{
key: 'addEvent',
value: function addEvent(actions) {
this.actions = actions;
this._els.iconColorpicker.on('change', this._changeColorHandler.bind(this));
this._els.registIconButton.addEventListener('change', this._registeIconHandler.bind(this));
this._els.addIconButton.addEventListener('click', this._addIconHandler.bind(this));
}
/**
* Clear icon type
*/
}, {
key: 'clearIconType',
value: function clearIconType() {
this._els.addIconButton.classList.remove(this.iconType);
this.iconType = null;
}
/**
* Register default icon
*/
}, {
key: 'registDefaultIcon',
value: function registDefaultIcon() {
var _this2 = this;
_tuiCodeSnippet2.default.forEach(_consts.defaultIconPath, function (path, type) {
_this2.actions.registDefalutIcons(type, path);
});
}
/**
* Set icon picker color
* @param {string} iconColor - rgb color string
*/
}, {
key: 'setIconPickerColor',
value: function setIconPickerColor(iconColor) {
this._els.iconColorpicker.color = iconColor;
}
/**
* Returns the menu to its default state.
*/
}, {
key: 'changeStandbyMode',
value: function changeStandbyMode() {
this.clearIconType();
this.actions.cancelAddIcon();
}
/**
* Change icon color
* @param {string} color - color for change
* @private
*/
}, {
key: '_changeColorHandler',
value: function _changeColorHandler(color) {
color = color || 'transparent';
this.actions.changeColor(color);
}
/**
* Change icon color
* @param {object} event - add button event object
* @private
*/
}, {
key: '_addIconHandler',
value: function _addIconHandler(event) {
var button = event.target.closest('.tui-image-editor-button');
if (button) {
var iconType = button.getAttribute('data-icontype');
var iconColor = this._els.iconColorpicker.color;
this.actions.discardSelection();
this.actions.changeSelectableAll(false);
this._els.addIconButton.classList.remove(this.iconType);
this._els.addIconButton.classList.add(iconType);
if (this.iconType === iconType) {
this.changeStandbyMode();
} else {
this.actions.addIcon(iconType, iconColor);
this.iconType = iconType;
}
}
}
/**
* register icon
* @param {object} event - file change event object
* @private
*/
}, {
key: '_registeIconHandler',
value: function _registeIconHandler(event) {
var imgUrl = void 0;
if (!_util.isSupportFileApi) {
alert('This browser does not support file-api');
}
var _event$target$files = event.target.files,
file = _event$target$files[0];
if (file) {
imgUrl = URL.createObjectURL(file);
this.actions.registCustomIcon(imgUrl, file);
}
}
}]);
return Icon;
}(_submenuBase2.default);
exports.default = Icon;
/***/ }),
/* 97 */
/***/ (function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (_ref) {
var _ref$iconStyle = _ref.iconStyle,
normal = _ref$iconStyle.normal,
active = _ref$iconStyle.active;
return "\n <ul class=\"tui-image-editor-submenu-item\">\n <li id=\"tie-icon-add-button\">\n <div class=\"tui-image-editor-button\" data-icontype=\"icon-arrow\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-icon-arrow\"\n class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-icon-arrow\"\n class=\"active\"/>\n </svg>\n </div>\n <label>\n Arrow\n </label>\n </div>\n <div class=\"tui-image-editor-button\" data-icontype=\"icon-arrow-2\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-icon-arrow-2\"\n class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-icon-arrow-2\"\n class=\"active\"/>\n </svg>\n </div>\n <label>\n Arrow-2\n </label>\n </div>\n <div class=\"tui-image-editor-button\" data-icontype=\"icon-arrow-3\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-icon-arrow-3\"\n class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-icon-arrow-3\"\n class=\"active\"/>\n </svg>\n </div>\n <label>\n Arrow-3\n </label>\n </div>\n <div class=\"tui-image-editor-button\" data-icontype=\"icon-star\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-icon-star\" class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-icon-star\" class=\"active\"/>\n </svg>\n </div>\n <label>\n Star-1\n </label>\n </div>\n <div class=\"tui-image-editor-button\" data-icontype=\"icon-star-2\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-icon-star-2\"\n class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-icon-star-2\"\n class=\"active\"/>\n </svg>\n </div>\n <label>\n Star-2\n </label>\n </div>\n\n <div class=\"tui-image-editor-button\" data-icontype=\"icon-polygon\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-icon-polygon\"\n class=\"normal\"/>\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-icon-polygon\"\n class=\"active\"/>\n </svg>\n </div>\n <label>\n Polygon\n </label>\n </div>\n\n <div class=\"tui-image-editor-button\" data-icontype=\"icon-location\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-icon-location\"\n class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-icon-location\"\n class=\"active\"/>\n </svg>\n </div>\n <label>\n Location\n </label>\n </div>\n\n <div class=\"tui-image-editor-button\" data-icontype=\"icon-heart\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-icon-heart\"\n class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-icon-heart\"\n class=\"active\"/>\n </svg>\n </div>\n <label>\n Heart\n </label>\n </div>\n\n <div class=\"tui-image-editor-button\" data-icontype=\"icon-bubble\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-icon-bubble\"\n class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-icon-bubble\"\n class=\"active\"/>\n </svg>\n </div>\n <label>\n Bubble\n </label>\n </div>\n </li>\n <li class=\"tui-image-editor-partition\">\n <div></div>\n </li>\n <li id=\"tie-icon-add-button\">\n <div class=\"tui-image-editor-button\" style=\"margin:0\">\n <div>\n <input type=\"file\" accept=\"image/*\" id=\"tie-icon-image-file\">\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-icon-load\" class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-icon-load\" class=\"active\"/>\n </svg>\n </div>\n <label>\n Custom icon\n </label>\n </div>\n </li>\n <li class=\"tui-image-editor-partition\">\n <div></div>\n </li>\n <li>\n <div id=\"tie-icon-color\" title=\"Color\"></div>\n </li>\n </ul>\n";
};
/***/ }),
/* 98 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _util = __webpack_require__(72);
var _util2 = _interopRequireDefault(_util);
var _colorpicker = __webpack_require__(81);
var _colorpicker2 = _interopRequireDefault(_colorpicker);
var _range = __webpack_require__(83);
var _range2 = _interopRequireDefault(_range);
var _submenuBase = __webpack_require__(84);
var _submenuBase2 = _interopRequireDefault(_submenuBase);
var _draw = __webpack_require__(99);
var _draw2 = _interopRequireDefault(_draw);
var _consts = __webpack_require__(73);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var DRAW_OPACITY = 0.7;
/**
* Draw ui class
* @class
* @ignore
*/
var Draw = function (_Submenu) {
_inherits(Draw, _Submenu);
function Draw(subMenuElement, _ref) {
var iconStyle = _ref.iconStyle,
menuBarPosition = _ref.menuBarPosition;
_classCallCheck(this, Draw);
var _this = _possibleConstructorReturn(this, (Draw.__proto__ || Object.getPrototypeOf(Draw)).call(this, subMenuElement, {
name: 'draw',
iconStyle: iconStyle,
menuBarPosition: menuBarPosition,
templateHtml: _draw2.default
}));
_this._els = {
lineSelectButton: _this.selector('#tie-draw-line-select-button'),
drawColorpicker: new _colorpicker2.default(_this.selector('#tie-draw-color'), '#00a9ff', _this.toggleDirection),
drawRange: new _range2.default(_this.selector('#tie-draw-range'), _consts.defaultDrawRangeValus),
drawRangeValue: _this.selector('#tie-draw-range-value')
};
_this.type = null;
_this.color = _this._els.drawColorpicker.color;
_this.width = _this._els.drawRange.value;
return _this;
}
/**
* Add event for draw
* @param {Object} actions - actions for crop
* @param {Function} actions.setDrawMode - set draw mode
*/
_createClass(Draw, [{
key: 'addEvent',
value: function addEvent(actions) {
this.actions = actions;
this._els.lineSelectButton.addEventListener('click', this._changeDrawType.bind(this));
this._els.drawColorpicker.on('change', this._changeDrawColor.bind(this));
this._els.drawRange.on('change', this._changeDrawRange.bind(this));
this._els.drawRangeValue.value = this._els.drawRange.value;
this._els.drawRangeValue.setAttribute('readonly', true);
}
/**
* set draw mode - action runner
*/
}, {
key: 'setDrawMode',
value: function setDrawMode() {
this.actions.setDrawMode(this.type, {
width: this.width,
color: _util2.default.getRgb(this.color, DRAW_OPACITY)
});
}
/**
* Returns the menu to its default state.
*/
}, {
key: 'changeStandbyMode',
value: function changeStandbyMode() {
this.type = null;
this.actions.stopDrawingMode();
this.actions.changeSelectableAll(true);
this._els.lineSelectButton.classList.remove('free');
this._els.lineSelectButton.classList.remove('line');
}
/**
* Executed when the menu starts.
*/
}, {
key: 'changeStartMode',
value: function changeStartMode() {
this.type = 'free';
this._els.lineSelectButton.classList.add('free');
this.setDrawMode();
}
/**
* Change draw type event
* @param {object} event - line select event
* @private
*/
}, {
key: '_changeDrawType',
value: function _changeDrawType(event) {
var button = event.target.closest('.tui-image-editor-button');
if (button) {
var lineType = this.getButtonType(button, ['free', 'line']);
this.actions.discardSelection();
if (this.type === lineType) {
this.changeStandbyMode();
return;
}
this.changeStandbyMode();
this.type = lineType;
this._els.lineSelectButton.classList.add(lineType);
this.setDrawMode();
}
}
/**
* Change drawing color
* @param {string} color - select drawing color
* @private
*/
}, {
key: '_changeDrawColor',
value: function _changeDrawColor(color) {
this.color = color || 'transparent';
if (!this.type) {
this.changeStartMode();
} else {
this.setDrawMode();
}
}
/**
* Change drawing Range
* @param {number} value - select drawing range
* @private
*/
}, {
key: '_changeDrawRange',
value: function _changeDrawRange(value) {
value = _util2.default.toInteger(value);
this._els.drawRangeValue.value = value;
this.width = value;
if (!this.type) {
this.changeStartMode();
} else {
this.setDrawMode();
}
}
}]);
return Draw;
}(_submenuBase2.default);
exports.default = Draw;
/***/ }),
/* 99 */
/***/ (function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (_ref) {
var _ref$iconStyle = _ref.iconStyle,
normal = _ref$iconStyle.normal,
active = _ref$iconStyle.active;
return "\n <ul class=\"tui-image-editor-submenu-item\">\n <li id=\"tie-draw-line-select-button\">\n <div class=\"tui-image-editor-button free\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-draw-free\" class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-draw-free\" class=\"active\"/>\n </svg>\n </div>\n <label>\n Free\n </label>\n </div>\n <div class=\"tui-image-editor-button line\">\n <div>\n <svg class=\"svg_ic-submenu\">\n <use xlink:href=\"" + normal.path + "#" + normal.name + "-ic-draw-line\" class=\"normal\"/>\n <use xlink:href=\"" + active.path + "#" + active.name + "-ic-draw-line\" class=\"active\"/>\n </svg>\n </div>\n <label>\n Straight\n </label>\n </div>\n </li>\n <li class=\"tui-image-editor-partition\">\n <div></div>\n </li>\n <li>\n <div id=\"tie-draw-color\" title=\"Color\"></div>\n </li>\n <li class=\"tui-image-editor-partition only-left-right\">\n <div></div>\n </li>\n <li class=\"tui-image-editor-newline tui-image-editor-range-wrap\">\n <label class=\"range\">Range</label>\n <div id=\"tie-draw-range\"></div>\n <input id=\"tie-draw-range-value\" class=\"tui-image-editor-range-value\" value=\"0\" />\n </li>\n </ul>\n";
};
/***/ }),
/* 100 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _tuiCodeSnippet = __webpack_require__(3);
var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet);
var _colorpicker = __webpack_require__(81);
var _colorpicker2 = _interopRequireDefault(_colorpicker);
var _range = __webpack_require__(83);
var _range2 = _interopRequireDefault(_range);
var _submenuBase = __webpack_require__(84);
var _submenuBase2 = _interopRequireDefault(_submenuBase);
var _filter = __webpack_require__(101);
var _filter2 = _interopRequireDefault(_filter);
var _util = __webpack_require__(72);
var _consts = __webpack_require__(73);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var PICKER_CONTROL_HEIGHT = '130px';
var BLEND_OPTIONS = ['add', 'diff', 'subtract', 'multiply', 'screen', 'lighten', 'darken'];
var FILTER_OPTIONS = ['grayscale', 'invert', 'sepia', 'sepia2', 'blur', 'sharpen', 'emboss', 'remove-white', 'gradient-transparency', 'brightness', 'noise', 'pixelate', 'color-filter', 'tint', 'multiply', 'blend'];
/**
* Filter ui class
* @class
* @ignore
*/
var Filter = function (_Submenu) {
_inherits(Filter, _Submenu);
function Filter(subMenuElement, _ref) {
var iconStyle = _ref.iconStyle,
menuBarPosition = _ref.menuBarPosition;
_classCallCheck(this, Filter);
var _this = _possibleConstructorReturn(this, (Filter.__proto__ || Object.getPrototypeOf(Filter)).call(this, subMenuElement, {
name: 'filter',
iconStyle: iconStyle,
menuBarPosition: menuBarPosition,
templateHtml: _filter2.default
}));
_this.selectBoxShow = false;
_this.checkedMap = {};
_this._makeControlElement();
return _this;
}
/**
* Add event for filter
* @param {Object} actions - actions for crop
* @param {Function} actions.applyFilter - apply filter option
*/
_createClass(Filter, [{
key: 'addEvent',
value: function addEvent(_ref2) {
var _this2 = this;
var applyFilter = _ref2.applyFilter;
var changeRangeValue = this._changeRangeValue.bind(this, applyFilter);
_tuiCodeSnippet2.default.forEach(FILTER_OPTIONS, function (filterName) {
var filterCheckElement = _this2.selector('#tie-' + filterName);
var filterNameCamelCase = (0, _util.toCamelCase)(filterName);
_this2.checkedMap[filterNameCamelCase] = filterCheckElement;
filterCheckElement.addEventListener('change', function () {
return changeRangeValue(filterNameCamelCase);
});
});
this._els.removewhiteThresholdRange.on('change', function () {
return changeRangeValue('removeWhite');
});
this._els.removewhiteDistanceRange.on('change', function () {
return changeRangeValue('removeWhite');
});
this._els.gradientTransparencyRange.on('change', function () {
return changeRangeValue('gradientTransparency');
});
this._els.colorfilterThresholeRange.on('change', function () {
return changeRangeValue('colorFilter');
});
this._els.pixelateRange.on('change', function () {
return changeRangeValue('pixelate');
});
this._els.noiseRange.on('change', function () {
return changeRangeValue('noise');
});
this._els.brightnessRange.on('change', function () {
return changeRangeValue('brightness');
});
this._els.blendType.addEventListener('change', function () {
return changeRangeValue('blend');
});
this._els.filterBlendColor.on('change', function () {
return changeRangeValue('blend');
});
this._els.filterMultiplyColor.on('change', function () {
return changeRangeValue('multiply');
});
this._els.tintOpacity.on('change', function () {
return changeRangeValue('tint');
});
this._els.filterTintColor.on('change', function () {
return changeRangeValue('tint');
});
this._els.blendType.addEventListener('click', function (event) {
return event.stopPropagation();
});
this._els.filterMultiplyColor.on('changeShow', this.colorPickerChangeShow.bind(this));
this._els.filterTintColor.on('changeShow', this.colorPickerChangeShow.bind(this));
this._els.filterBlendColor.on('changeShow', this.colorPickerChangeShow.bind(this));
}
/**
* Add event for filter
* @param {Function} applyFilter - actions for firter
* @param {string} filterName - filter name
*/
}, {
key: '_changeRangeValue',
value: function _changeRangeValue(applyFilter, filterName) {
var apply = this.checkedMap[filterName].checked;
var type = filterName;
var checkboxGroup = this.checkedMap[filterName].closest('.tui-image-editor-checkbox-group');
if (checkboxGroup) {
if (apply) {
checkboxGroup.classList.remove('tui-image-editor-disabled');
} else {
checkboxGroup.classList.add('tui-image-editor-disabled');
}
}
applyFilter(apply, type, this._getFilterOption(type));
}
/**
* Get filter option
* @param {String} type - filter type
* @returns {Object} filter option object
* @private
*/
}, {
key: '_getFilterOption',
value: function _getFilterOption(type) {
// eslint-disable-line
var option = {};
switch (type) {
case 'removeWhite':
option.threshold = (0, _util.toInteger)(this._els.removewhiteThresholdRange.value);
option.distance = (0, _util.toInteger)(this._els.removewhiteDistanceRange.value);
break;
case 'gradientTransparency':
option.threshold = (0, _util.toInteger)(this._els.gradientTransparencyRange.value);
break;
case 'colorFilter':
option.color = '#FFFFFF';
option.threshold = this._els.colorfilterThresholeRange.value;
break;
case 'pixelate':
option.blocksize = (0, _util.toInteger)(this._els.pixelateRange.value);
break;
case 'noise':
option.noise = (0, _util.toInteger)(this._els.noiseRange.value);
break;
case 'brightness':
option.brightness = (0, _util.toInteger)(this._els.brightnessRange.value);
break;
case 'blend':
option.color = this._els.filterBlendColor.color;
option.mode = this._els.blendType.value;
break;
case 'multiply':
option.color = this._els.filterMultiplyColor.color;
break;
case 'tint':
option.color = this._els.filterTintColor.color;
option.opacity = this._els.tintOpacity.value;
break;
default:
break;
}
return option;
}
/**
* Make submenu range and colorpicker control
* @private
*/
}, {
key: '_makeControlElement',
value: function _makeControlElement() {
var selector = this.selector;
this._els = {
removewhiteThresholdRange: new _range2.default(selector('#tie-removewhite-threshold-range'), _consts.defaultFilterRangeValus.removewhiteThresholdRange),
removewhiteDistanceRange: new _range2.default(selector('#tie-removewhite-distance-range'), _consts.defaultFilterRangeValus.removewhiteDistanceRange),
gradientTransparencyRange: new _range2.default(selector('#tie-gradient-transparency-range'), _consts.defaultFilterRangeValus.gradientTransparencyRange),
brightnessRange: new _range2.default(selector('#tie-brightness-range'), _consts.defaultFilterRangeValus.brightnessRange),
noiseRange: new _range2.default(selector('#tie-noise-range'), _consts.defaultFilterRangeValus.noiseRange),
pixelateRange: new _range2.default(selector('#tie-pixelate-range'), _consts.defaultFilterRangeValus.pixelateRange),
colorfilterThresholeRange: new _range2.default(selector('#tie-colorfilter-threshole-range'), _consts.defaultFilterRangeValus.colorfilterThresholeRange),
filterTintColor: new _colorpicker2.default(selector('#tie-filter-tint-color'), '#03bd9e', this.toggleDirection),
filterMultiplyColor: new _colorpicker2.default(selector('#tie-filter-multiply-color'), '#515ce6', this.toggleDirection),
filterBlendColor: new _colorpicker2.default(selector('#tie-filter-blend-color'), '#ffbb3b', this.toggleDirection)
};
this._els.tintOpacity = this._pickerWithRange(this._els.filterTintColor.pickerControl);
this._els.blendType = this._pickerWithSelectbox(this._els.filterBlendColor.pickerControl);
this.colorPickerControls.push(this._els.filterTintColor);
this.colorPickerControls.push(this._els.filterMultiplyColor);
this.colorPickerControls.push(this._els.filterBlendColor);
}
/**
* Make submenu control for picker & range mixin
* @param {HTMLElement} pickerControl - pickerControl dom element
* @returns {Range}
* @private
*/
}, {
key: '_pickerWithRange',
value: function _pickerWithRange(pickerControl) {
var rangeWrap = document.createElement('div');
var rangelabel = document.createElement('label');
var range = document.createElement('div');
range.id = 'tie-filter-tint-opacity';
rangelabel.innerHTML = 'Opacity';
rangeWrap.appendChild(rangelabel);
rangeWrap.appendChild(range);
pickerControl.appendChild(rangeWrap);
pickerControl.style.height = PICKER_CONTROL_HEIGHT;
return new _range2.default(range, _consts.defaultFilterRangeValus.tintOpacityRange);
}
/**
* Make submenu control for picker & selectbox
* @param {HTMLElement} pickerControl - pickerControl dom element
* @returns {HTMLElement}
* @private
*/
}, {
key: '_pickerWithSelectbox',
value: function _pickerWithSelectbox(pickerControl) {
var selectlistWrap = document.createElement('div');
var selectlist = document.createElement('select');
var optionlist = document.createElement('ul');
selectlistWrap.className = 'tui-image-editor-selectlist-wrap';
optionlist.className = 'tui-image-editor-selectlist';
selectlistWrap.appendChild(selectlist);
selectlistWrap.appendChild(optionlist);
this._makeSelectOptionList(selectlist);
pickerControl.appendChild(selectlistWrap);
pickerControl.style.height = PICKER_CONTROL_HEIGHT;
this._drawSelectOptionList(selectlist, optionlist);
this._pickerWithSelectboxForAddEvent(selectlist, optionlist);
return selectlist;
}
/**
* Make selectbox option list custom style
* @param {HTMLElement} selectlist - selectbox element
* @param {HTMLElement} optionlist - custom option list item element
* @private
*/
}, {
key: '_drawSelectOptionList',
value: function _drawSelectOptionList(selectlist, optionlist) {
var options = selectlist.querySelectorAll('option');
_tuiCodeSnippet2.default.forEach(options, function (option) {
var optionElement = document.createElement('li');
optionElement.innerHTML = option.innerHTML;
optionElement.setAttribute('data-item', option.value);
optionlist.appendChild(optionElement);
});
}
/**
* custome selectbox custom event
* @param {HTMLElement} selectlist - selectbox element
* @param {HTMLElement} optionlist - custom option list item element
* @private
*/
}, {
key: '_pickerWithSelectboxForAddEvent',
value: function _pickerWithSelectboxForAddEvent(selectlist, optionlist) {
var _this3 = this;
optionlist.addEventListener('click', function (event) {
var optionValue = event.target.getAttribute('data-item');
var fireEvent = document.createEvent('HTMLEvents');
selectlist.querySelector('[value="' + optionValue + '"]').selected = true;
fireEvent.initEvent('change', true, true);
selectlist.dispatchEvent(fireEvent);
_this3.selectBoxShow = false;
optionlist.style.display = 'none';
});
selectlist.addEventListener('mousedown', function (event) {
event.preventDefault();
_this3.selectBoxShow = !_this3.selectBoxShow;
optionlist.style.display = _this3.selectBoxShow ? 'block' : 'none';
optionlist.setAttribute('data-selectitem', selectlist.value);
optionlist.querySelector('[data-item=\'' + selectlist.value + '\']').classList.add('active');
});
}
/**
* Make option list for select control
* @param {HTMLElement} selectlist - blend option select list element
* @private
*/
}, {
key: '_makeSelectOptionList',
value: function _makeSelectOptionList(selectlist) {
_tuiCodeSnippet2.default.forEach(BLEND_OPTIONS, function (option) {
var selectOption = document.createElement('option');
selectOption.setAttribute('value', option);
selectOption.innerHTML = option.replace(/^[a-z]/, function ($0) {
return $0.toUpperCase();
});
selectlist.appendChild(selectOption);
});
}
}]);
return Filter;
}(_submenuBase2.default);
exports.default = Filter;
/***/ }),
/* 101 */
/***/ (function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function () {
return "\n <ul class=\"tui-image-editor-submenu-item\">\n <li class=\"tui-image-editor-submenu-align\">\n <div class=\"tui-image-editor-checkbox-wrap fixed-width\">\n <div class=\"tui-image-editor-checkbox\">\n <input type=\"checkbox\" id=\"tie-grayscale\">\n <label for=\"tie-grayscale\">Grayscale</label>\n </div>\n <div class=\"tui-image-editor-checkbox\">\n <input type=\"checkbox\" id=\"tie-invert\">\n <label for=\"tie-invert\">Invert</label>\n </div>\n <div class=\"tui-image-editor-checkbox\">\n <input type=\"checkbox\" id=\"tie-sepia\">\n <label for=\"tie-sepia\">Sepia</label>\n </div>\n <div class=\"tui-image-editor-checkbox\">\n <input type=\"checkbox\" id=\"tie-sepia2\">\n <label for=\"tie-sepia2\">Sepia2</label>\n </div>\n <div class=\"tui-image-editor-checkbox\">\n <input type=\"checkbox\" id=\"tie-blur\">\n <label for=\"tie-blur\">Blur</label>\n </div>\n <div class=\"tui-image-editor-checkbox\">\n <input type=\"checkbox\" id=\"tie-sharpen\">\n <label for=\"tie-sharpen\">Sharpen</label>\n </div>\n <div class=\"tui-image-editor-checkbox\">\n <input type=\"checkbox\" id=\"tie-emboss\">\n <label for=\"tie-emboss\">Emboss</label>\n </div>\n </div>\n </li>\n <li class=\"tui-image-editor-partition\">\n <div></div>\n </li>\n <li class=\"tui-image-editor-submenu-align\">\n <div class=\"tui-image-editor-checkbox-group tui-image-editor-disabled\" style=\"margin-bottom: 7px;\">\n <div class=\"tui-image-editor-checkbox-wrap\">\n <div class=\"tui-image-editor-checkbox\">\n <input type=\"checkbox\" id=\"tie-remove-white\">\n <label for=\"tie-remove-white\">Remove White</label>\n </div>\n </div>\n <div class=\"tui-image-editor-newline tui-image-editor-range-wrap short\">\n <label>Threshold</label>\n <div id=\"tie-removewhite-threshold-range\"></div>\n </div>\n <div class=\"tui-image-editor-newline tui-image-editor-range-wrap short\">\n <label>Distance</label>\n <div id=\"tie-removewhite-distance-range\"></div>\n </div>\n </div>\n <div class=\"tui-image-editor-checkbox-group tui-image-editor-disabled\">\n <div class=\"tui-image-editor-newline tui-image-editor-checkbox-wrap\">\n <div class=\"tui-image-editor-checkbox\">\n <input type=\"checkbox\" id=\"tie-gradient-transparency\">\n <label for=\"tie-gradient-transparency\">Grayscale</label>\n </div>\n </div>\n <div class=\"tui-image-editor-newline tui-image-editor-range-wrap short\">\n <label>Value</label>\n <div id=\"tie-gradient-transparency-range\"></div>\n </div>\n </div>\n </li>\n <li class=\"tui-image-editor-partition only-left-right\">\n <div></div>\n </li>\n <li class=\"tui-image-editor-submenu-align\">\n <div class=\"tui-image-editor-checkbox-group tui-image-editor-disabled\">\n <div class=\"tui-image-editor-checkbox\">\n <input type=\"checkbox\" id=\"tie-brightness\">\n <label for=\"tie-brightness\">Brightness</label>\n </div>\n <div class=\"tui-image-editor-range-wrap short\">\n <div id=\"tie-brightness-range\"></div>\n </div>\n </div>\n <div class=\"tui-image-editor-checkbox-group tui-image-editor-disabled\">\n <div class=\"tui-image-editor-checkbox\">\n <input type=\"checkbox\" id=\"tie-noise\">\n <label for=\"tie-noise\">Noise</label>\n </div>\n <div class=\"tui-image-editor-range-wrap short\">\n <div id=\"tie-noise-range\"></div>\n </div>\n </div>\n\n <div class=\"tui-image-editor-checkbox-group tui-image-editor-disabled\">\n <div class=\"tui-image-editor-checkbox\">\n <input type=\"checkbox\" id=\"tie-pixelate\">\n <label for=\"tie-pixelate\">Pixelate</label>\n </div>\n <div class=\"tui-image-editor-range-wrap short\">\n <div id=\"tie-pixelate-range\"></div>\n </div>\n </div>\n <div class=\"tui-image-editor-checkbox-group tui-image-editor-disabled\">\n <div class=\"tui-image-editor-newline tui-image-editor-checkbox-wrap\">\n <div class=\"tui-image-editor-checkbox\">\n <input type=\"checkbox\" id=\"tie-color-filter\">\n <label for=\"tie-color-filter\">Color Filter</label>\n </div>\n </div>\n <div class=\"tui-image-editor-newline tui-image-editor-range-wrap short\">\n <label>Threshold</label>\n <div id=\"tie-colorfilter-threshole-range\"></div>\n </div>\n </div>\n </li>\n <li class=\"tui-image-editor-partition\">\n <div></div>\n </li>\n <li>\n <div class=\"filter-color-item\">\n <div id=\"tie-filter-tint-color\" title=\"Tint\"></div>\n <div class=\"tui-image-editor-checkbox\">\n <input type=\"checkbox\" id=\"tie-tint\">\n <label for=\"tie-tint\"></label>\n </div>\n </div>\n <div class=\"filter-color-item\">\n <div id=\"tie-filter-multiply-color\" title=\"Multiply\"></div>\n <div class=\"tui-image-editor-checkbox\">\n <input type=\"checkbox\" id=\"tie-multiply\">\n <label for=\"tie-multiply\"></label>\n </div>\n </div>\n <div class=\"filter-color-item\">\n <div id=\"tie-filter-blend-color\" title=\"Blend\"></div>\n <div class=\"tui-image-editor-checkbox\">\n <input type=\"checkbox\" id=\"tie-blend\">\n <label for=\"tie-blend\"></label>\n </div>\n </div>\n </li>\n </ul>\n";
};
/***/ }),
/* 102 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _tuiCodeSnippet = __webpack_require__(3);
var _util = __webpack_require__(72);
var _util2 = _interopRequireDefault(_util);
var _imagetracer = __webpack_require__(103);
var _imagetracer2 = _interopRequireDefault(_imagetracer);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = {
/**
* Get ui actions
* @returns {Object} actions for ui
* @private
*/
getActions: function getActions() {
return {
main: this._mainAction(),
shape: this._shapeAction(),
crop: this._cropAction(),
flip: this._flipAction(),
rotate: this._rotateAction(),
text: this._textAction(),
mask: this._maskAction(),
draw: this._drawAction(),
icon: this._iconAction(),
filter: this._filterAction()
};
},
/**
* Main Action
* @returns {Object} actions for ui main
* @private
*/
_mainAction: function _mainAction() {
var _this = this;
var exitCropOnAction = function exitCropOnAction() {
if (_this.ui.submenu === 'crop') {
_this.stopDrawingMode();
_this.ui.changeMenu('crop');
}
};
return (0, _tuiCodeSnippet.extend)({
initLoadImage: function initLoadImage(imagePath, imageName) {
return _this.loadImageFromURL(imagePath, imageName).then(function (sizeValue) {
exitCropOnAction();
_this.ui.initializeImgUrl = imagePath;
_this.ui.resizeEditor({ imageSize: sizeValue });
_this.clearUndoStack();
});
},
undo: function undo() {
if (!_this.isEmptyUndoStack()) {
exitCropOnAction();
_this.undo();
}
},
redo: function redo() {
if (!_this.isEmptyRedoStack()) {
exitCropOnAction();
_this.redo();
}
},
reset: function reset() {
exitCropOnAction();
_this.loadImageFromURL(_this.ui.initializeImgUrl, 'resetImage').then(function (sizeValue) {
exitCropOnAction();
_this.ui.resizeEditor({ imageSize: sizeValue });
_this.clearUndoStack();
});
},
delete: function _delete() {
_this.ui.changeDeleteButtonEnabled(false);
exitCropOnAction();
_this.removeActiveObject();
_this.activeObjectId = null;
},
deleteAll: function deleteAll() {
exitCropOnAction();
_this.clearObjects();
_this.ui.changeDeleteButtonEnabled(false);
_this.ui.changeDeleteAllButtonEnabled(false);
},
load: function load(file) {
if (!_util2.default.isSupportFileApi()) {
alert('This browser does not support file-api');
}
_this.ui.initializeImgUrl = URL.createObjectURL(file);
_this.loadImageFromFile(file).then(function () {
exitCropOnAction();
_this.clearUndoStack();
_this.ui.resizeEditor();
})['catch'](function (message) {
return Promise.reject(message);
});
},
download: function download() {
var dataURL = _this.toDataURL();
var imageName = _this.getImageName();
var blob = void 0,
type = void 0,
w = void 0;
if (_util2.default.isSupportFileApi() && window.saveAs) {
blob = _util2.default.base64ToBlob(dataURL);
type = blob.type.split('/')[1];
if (imageName.split('.').pop() !== type) {
imageName += '.' + type;
}
saveAs(blob, imageName); // eslint-disable-line
} else {
w = window.open();
w.document.body.innerHTML = '<img src=\'' + dataURL + '\'>';
}
}
}, this._commonAction());
},
/**
* Icon Action
* @returns {Object} actions for ui icon
* @private
*/
_iconAction: function _iconAction() {
var _this2 = this;
var cacheIconType = void 0;
var cacheIconColor = void 0;
var startX = void 0;
var startY = void 0;
var iconWidth = void 0;
var iconHeight = void 0;
var objId = void 0;
this.on({
'iconCreateResize': function iconCreateResize(_ref) {
var moveOriginPointer = _ref.moveOriginPointer;
var scaleX = (moveOriginPointer.x - startX) / iconWidth;
var scaleY = (moveOriginPointer.y - startY) / iconHeight;
_this2.setObjectPropertiesQuietly(objId, {
scaleX: Math.abs(scaleX * 2),
scaleY: Math.abs(scaleY * 2)
});
},
'iconCreateEnd': function iconCreateEnd() {
_this2.ui.icon.clearIconType();
_this2.changeSelectableAll(true);
}
});
var mouseDown = function mouseDown(e, originPointer) {
startX = originPointer.x;
startY = originPointer.y;
_this2.addIcon(cacheIconType, {
left: originPointer.x,
top: originPointer.y,
fill: cacheIconColor
}).then(function (obj) {
objId = obj.id;
iconWidth = obj.width;
iconHeight = obj.height;
});
};
return (0, _tuiCodeSnippet.extend)({
changeColor: function changeColor(color) {
if (_this2.activeObjectId) {
_this2.changeIconColor(_this2.activeObjectId, color);
}
},
addIcon: function addIcon(iconType, iconColor) {
cacheIconType = iconType;
cacheIconColor = iconColor;
// this.readyAddIcon();
_this2.changeCursor('crosshair');
_this2.off('mousedown');
_this2.once('mousedown', mouseDown.bind(_this2));
},
cancelAddIcon: function cancelAddIcon() {
_this2.off('mousedown');
_this2.ui.icon.clearIconType();
_this2.changeSelectableAll(true);
_this2.changeCursor('default');
},
registDefalutIcons: function registDefalutIcons(type, path) {
var iconObj = {};
iconObj[type] = path;
_this2.registerIcons(iconObj);
},
registCustomIcon: function registCustomIcon(imgUrl, file) {
var imagetracer = new _imagetracer2.default();
imagetracer.imageToSVG(imgUrl, function (svgstr) {
var _svgstr$match = svgstr.match(/path[^>]*d="([^"]*)"/),
svgPath = _svgstr$match[1];
var iconObj = {};
iconObj[file.name] = svgPath;
_this2.registerIcons(iconObj);
_this2.addIcon(file.name, {
left: 100,
top: 100
});
}, _imagetracer2.default.tracerDefaultOption());
}
}, this._commonAction());
},
/**
* Draw Action
* @returns {Object} actions for ui draw
* @private
*/
_drawAction: function _drawAction() {
var _this3 = this;
return (0, _tuiCodeSnippet.extend)({
setDrawMode: function setDrawMode(type, settings) {
_this3.stopDrawingMode();
if (type === 'free') {
_this3.startDrawingMode('FREE_DRAWING', settings);
} else {
_this3.startDrawingMode('LINE_DRAWING', settings);
}
},
setColor: function setColor(color) {
_this3.setBrush({
color: color
});
}
}, this._commonAction());
},
/**
* Mask Action
* @returns {Object} actions for ui mask
* @private
*/
_maskAction: function _maskAction() {
var _this4 = this;
return (0, _tuiCodeSnippet.extend)({
loadImageFromURL: function loadImageFromURL(imgUrl, file) {
return _this4.loadImageFromURL(_this4.toDataURL(), 'FilterImage').then(function () {
_this4.addImageObject(imgUrl).then(function () {
URL.revokeObjectURL(file);
});
});
},
applyFilter: function applyFilter() {
_this4.applyFilter('mask', {
maskObjId: _this4.activeObjectId
});
}
}, this._commonAction());
},
/**
* Text Action
* @returns {Object} actions for ui text
* @private
*/
_textAction: function _textAction() {
var _this5 = this;
return (0, _tuiCodeSnippet.extend)({
changeTextStyle: function changeTextStyle(styleObj) {
if (_this5.activeObjectId) {
_this5.changeTextStyle(_this5.activeObjectId, styleObj);
}
}
}, this._commonAction());
},
/**
* Rotate Action
* @returns {Object} actions for ui rotate
* @private
*/
_rotateAction: function _rotateAction() {
var _this6 = this;
return (0, _tuiCodeSnippet.extend)({
rotate: function rotate(angle) {
_this6.rotate(angle);
_this6.ui.resizeEditor();
},
setAngle: function setAngle(angle) {
_this6.setAngle(angle);
_this6.ui.resizeEditor();
}
}, this._commonAction());
},
/**
* Shape Action
* @returns {Object} actions for ui shape
* @private
*/
_shapeAction: function _shapeAction() {
var _this7 = this;
return (0, _tuiCodeSnippet.extend)({
changeShape: function changeShape(changeShapeObject) {
if (_this7.activeObjectId) {
_this7.changeShape(_this7.activeObjectId, changeShapeObject);
}
},
setDrawingShape: function setDrawingShape(shapeType) {
_this7.setDrawingShape(shapeType);
}
}, this._commonAction());
},
/**
* Crop Action
* @returns {Object} actions for ui crop
* @private
*/
_cropAction: function _cropAction() {
var _this8 = this;
return (0, _tuiCodeSnippet.extend)({
crop: function crop() {
var cropRect = _this8.getCropzoneRect();
if (cropRect) {
_this8.crop(cropRect).then(function () {
_this8.stopDrawingMode();
_this8.ui.resizeEditor();
_this8.ui.changeMenu('crop');
})['catch'](function (message) {
return Promise.reject(message);
});
}
},
cancel: function cancel() {
_this8.stopDrawingMode();
_this8.ui.changeMenu('crop');
}
}, this._commonAction());
},
/**
* Flip Action
* @returns {Object} actions for ui flip
* @private
*/
_flipAction: function _flipAction() {
var _this9 = this;
return (0, _tuiCodeSnippet.extend)({
flip: function flip(flipType) {
return _this9[flipType]();
}
}, this._commonAction());
},
/**
* Filter Action
* @returns {Object} actions for ui filter
* @private
*/
_filterAction: function _filterAction() {
var _this10 = this;
return (0, _tuiCodeSnippet.extend)({
applyFilter: function applyFilter(applying, type, options) {
if (applying) {
_this10.applyFilter(type, options);
} else if (_this10.hasFilter(type)) {
_this10.removeFilter(type);
}
}
}, this._commonAction());
},
/**
* Image Editor Event Observer
*/
setReAction: function setReAction() {
var _this11 = this;
this.on({
undoStackChanged: function undoStackChanged(length) {
if (length) {
_this11.ui.changeUndoButtonStatus(true);
_this11.ui.changeResetButtonStatus(true);
} else {
_this11.ui.changeUndoButtonStatus(false);
_this11.ui.changeResetButtonStatus(false);
}
_this11.ui.resizeEditor();
},
redoStackChanged: function redoStackChanged(length) {
if (length) {
_this11.ui.changeRedoButtonStatus(true);
} else {
_this11.ui.changeRedoButtonStatus(false);
}
_this11.ui.resizeEditor();
},
/* eslint-disable complexity */
objectActivated: function objectActivated(obj) {
_this11.activeObjectId = obj.id;
_this11.ui.changeDeleteButtonEnabled(true);
_this11.ui.changeDeleteAllButtonEnabled(true);
if (obj.type === 'cropzone') {
_this11.ui.crop.changeApplyButtonStatus(true);
} else if (['rect', 'circle', 'triangle'].indexOf(obj.type) > -1) {
_this11.stopDrawingMode();
if (_this11.ui.submenu !== 'shape') {
_this11.ui.changeMenu('shape', false, false);
}
_this11.ui.shape.setShapeStatus({
strokeColor: obj.stroke,
strokeWidth: obj.strokeWidth,
fillColor: obj.fill
});
_this11.ui.shape.setMaxStrokeValue(Math.min(obj.width, obj.height));
} else if (obj.type === 'path' || obj.type === 'line') {
if (_this11.ui.submenu !== 'draw') {
_this11.ui.changeMenu('draw', false, false);
_this11.ui.draw.changeStandbyMode();
}
} else if (['i-text', 'text'].indexOf(obj.type) > -1) {
if (_this11.ui.submenu !== 'text') {
_this11.ui.changeMenu('text', false, false);
}
} else if (obj.type === 'icon') {
_this11.stopDrawingMode();
if (_this11.ui.submenu !== 'icon') {
_this11.ui.changeMenu('icon', false, false);
}
_this11.ui.icon.setIconPickerColor(obj.fill);
}
},
/* eslint-enable complexity */
addText: function addText(pos) {
_this11.addText('Double Click', {
position: pos.originPosition,
styles: {
fill: _this11.ui.text.textColor,
fontSize: _util2.default.toInteger(_this11.ui.text.fontSize),
fontFamily: 'Noto Sans'
}
}).then(function () {
_this11.changeCursor('default');
});
},
addObjectAfter: function addObjectAfter(obj) {
if (['rect', 'circle', 'triangle'].indexOf(obj.type) > -1) {
_this11.ui.shape.setMaxStrokeValue(Math.min(obj.width, obj.height));
_this11.ui.shape.changeStandbyMode();
}
},
objectScaled: function objectScaled(obj) {
if (['i-text', 'text'].indexOf(obj.type) > -1) {
_this11.ui.text.fontSize = _util2.default.toInteger(obj.fontSize);
} else if (['rect', 'circle', 'triangle'].indexOf(obj.type) >= 0) {
var width = obj.width,
height = obj.height;
var strokeValue = _this11.ui.shape.getStrokeValue();
if (width < strokeValue) {
_this11.ui.shape.setStrokeValue(width);
}
if (height < strokeValue) {
_this11.ui.shape.setStrokeValue(height);
}
}
},
selectionCleared: function selectionCleared() {
_this11.activeObjectId = null;
if (_this11.ui.submenu === 'text') {
_this11.changeCursor('text');
} else if (_this11.ui.submenu !== 'draw' && _this11.ui.submenu !== 'crop') {
_this11.stopDrawingMode();
}
}
});
},
/**
* Common Action
* @returns {Object} common actions for ui
* @private
*/
_commonAction: function _commonAction() {
var _this12 = this;
return {
modeChange: function modeChange(menu) {
switch (menu) {
case 'text':
_this12._changeActivateMode('TEXT');
break;
case 'crop':
_this12.startDrawingMode('CROPPER');
break;
case 'shape':
_this12._changeActivateMode('SHAPE');
_this12.setDrawingShape(_this12.ui.shape.type, _this12.ui.shape.options);
break;
default:
break;
}
},
deactivateAll: this.deactivateAll.bind(this),
changeSelectableAll: this.changeSelectableAll.bind(this),
discardSelection: this.discardSelection.bind(this),
stopDrawingMode: this.stopDrawingMode.bind(this)
};
},
/**
* Mixin
* @param {ImageEditor} ImageEditor instance
*/
mixin: function mixin(ImageEditor) {
(0, _tuiCodeSnippet.extend)(ImageEditor.prototype, this);
}
};
/***/ }),
/* 103 */
/***/ (function(module, exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/*
imagetracer.js version 1.2.4
Simple raster image tracer and vectorizer written in JavaScript.
andras@jankovics.net
*/
/*
The Unlicense / PUBLIC DOMAIN
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to http://unlicense.org/
*/
var ImageTracer = function () {
_createClass(ImageTracer, null, [{
key: 'tracerDefaultOption',
value: function tracerDefaultOption() {
return {
pathomit: 100,
ltres: 0.1,
qtres: 1,
scale: 1,
strokewidth: 5,
viewbox: false,
linefilter: true,
desc: false,
rightangleenhance: false,
pal: [{
r: 0,
g: 0,
b: 0,
a: 255
}, {
r: 255,
g: 255,
b: 255,
a: 255
}]
};
}
/* eslint-disable */
}]);
function ImageTracer() {
_classCallCheck(this, ImageTracer);
this.versionnumber = '1.2.4';
this.optionpresets = {
default: {
corsenabled: false,
ltres: 1,
qtres: 1,
pathomit: 8,
rightangleenhance: true,
colorsampling: 2,
numberofcolors: 16,
mincolorratio: 0,
colorquantcycles: 3,
layering: 0,
strokewidth: 1,
linefilter: false,
scale: 1,
roundcoords: 1,
viewbox: false,
desc: false,
lcpr: 0,
qcpr: 0,
blurradius: 0,
blurdelta: 20
},
'posterized1': {
colorsampling: 0,
numberofcolors: 2
},
'posterized2': {
numberofcolors: 4,
blurradius: 5
},
'curvy': {
ltres: 0.01,
linefilter: true,
rightangleenhance: false },
'sharp': { qtres: 0.01,
linefilter: false },
'detailed': { pathomit: 0,
roundcoords: 2,
ltres: 0.5,
qtres: 0.5,
numberofcolors: 64 },
'smoothed': { blurradius: 5,
blurdelta: 64 },
'grayscale': { colorsampling: 0,
colorquantcycles: 1,
numberofcolors: 7 },
'fixedpalette': { colorsampling: 0,
colorquantcycles: 1,
numberofcolors: 27 },
'randomsampling1': { colorsampling: 1,
numberofcolors: 8 },
'randomsampling2': { colorsampling: 1,
numberofcolors: 64 },
'artistic1': { colorsampling: 0,
colorquantcycles: 1,
pathomit: 0,
blurradius: 5,
blurdelta: 64,
ltres: 0.01,
linefilter: true,
numberofcolors: 16,
strokewidth: 2 },
'artistic2': { qtres: 0.01,
colorsampling: 0,
colorquantcycles: 1,
numberofcolors: 4,
strokewidth: 0 },
'artistic3': { qtres: 10,
ltres: 10,
numberofcolors: 8 },
'artistic4': { qtres: 10,
ltres: 10,
numberofcolors: 64,
blurradius: 5,
blurdelta: 256,
strokewidth: 2 },
'posterized3': { ltres: 1,
qtres: 1,
pathomit: 20,
rightangleenhance: true,
colorsampling: 0,
numberofcolors: 3,
mincolorratio: 0,
colorquantcycles: 3,
blurradius: 3,
blurdelta: 20,
strokewidth: 0,
linefilter: false,
roundcoords: 1,
pal: [{ r: 0,
g: 0,
b: 100,
a: 255 }, { r: 255,
g: 255,
b: 255,
a: 255 }] }
};
this.pathscan_combined_lookup = [[[-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1]], [[0, 1, 0, -1], [-1, -1, -1, -1], [-1, -1, -1, -1], [0, 2, -1, 0]], [[-1, -1, -1, -1], [-1, -1, -1, -1], [0, 1, 0, -1], [0, 0, 1, 0]], [[0, 0, 1, 0], [-1, -1, -1, -1], [0, 2, -1, 0], [-1, -1, -1, -1]], [[-1, -1, -1, -1], [0, 0, 1, 0], [0, 3, 0, 1], [-1, -1, -1, -1]], [[13, 3, 0, 1], [13, 2, -1, 0], [7, 1, 0, -1], [7, 0, 1, 0]], [[-1, -1, -1, -1], [0, 1, 0, -1], [-1, -1, -1, -1], [0, 3, 0, 1]], [[0, 3, 0, 1], [0, 2, -1, 0], [-1, -1, -1, -1], [-1, -1, -1, -1]], [[0, 3, 0, 1], [0, 2, -1, 0], [-1, -1, -1, -1], [-1, -1, -1, -1]], [[-1, -1, -1, -1], [0, 1, 0, -1], [-1, -1, -1, -1], [0, 3, 0, 1]], [[11, 1, 0, -1], [14, 0, 1, 0], [14, 3, 0, 1], [11, 2, -1, 0]], [[-1, -1, -1, -1], [0, 0, 1, 0], [0, 3, 0, 1], [-1, -1, -1, -1]], [[0, 0, 1, 0], [-1, -1, -1, -1], [0, 2, -1, 0], [-1, -1, -1, -1]], [[-1, -1, -1, -1], [-1, -1, -1, -1], [0, 1, 0, -1], [0, 0, 1, 0]], [[0, 1, 0, -1], [-1, -1, -1, -1], [-1, -1, -1, -1], [0, 2, -1, 0]], [[-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1]]];
this.gks = [[0.27901, 0.44198, 0.27901], [0.135336, 0.228569, 0.272192, 0.228569, 0.135336], [0.086776, 0.136394, 0.178908, 0.195843, 0.178908, 0.136394, 0.086776], [0.063327, 0.093095, 0.122589, 0.144599, 0.152781, 0.144599, 0.122589, 0.093095, 0.063327], [0.049692, 0.069304, 0.089767, 0.107988, 0.120651, 0.125194, 0.120651, 0.107988, 0.089767, 0.069304, 0.049692]];
this.specpalette = [{ r: 0, g: 0, b: 0, a: 255 }, { r: 128, g: 128, b: 128, a: 255 }, { r: 0, g: 0, b: 128, a: 255 }, { r: 64, g: 64, b: 128, a: 255 }, { r: 192, g: 192, b: 192, a: 255 }, { r: 255, g: 255, b: 255, a: 255 }, { r: 128, g: 128, b: 192, a: 255 }, { r: 0, g: 0, b: 192, a: 255 }, { r: 128, g: 0, b: 0, a: 255 }, { r: 128, g: 64, b: 64, a: 255 }, { r: 128, g: 0, b: 128, a: 255 }, { r: 168, g: 168, b: 168, a: 255 }, { r: 192, g: 128, b: 128, a: 255 }, { r: 192, g: 0, b: 0, a: 255 }, { r: 255, g: 255, b: 255, a: 255 }, { r: 0, g: 128, b: 0, a: 255 }];
}
_createClass(ImageTracer, [{
key: 'imageToSVG',
value: function imageToSVG(url, callback, options) {
var _this = this;
options = this.checkoptions(options);
this.loadImage(url, function (canvas) {
callback(_this.imagedataToSVG(_this.getImgdata(canvas), options));
}, options);
}
}, {
key: 'imagedataToSVG',
value: function imagedataToSVG(imgd, options) {
options = this.checkoptions(options);
var td = this.imagedataToTracedata(imgd, options);
return this.getsvgstring(td, options);
}
}, {
key: 'imageToTracedata',
value: function imageToTracedata(url, callback, options) {
var _this2 = this;
options = this.checkoptions(options);
this.loadImage(url, function (canvas) {
callback(_this2.imagedataToTracedata(_this2.getImgdata(canvas), options));
}, options);
}
}, {
key: 'imagedataToTracedata',
value: function imagedataToTracedata(imgd, options) {
options = this.checkoptions(options);
var ii = this.colorquantization(imgd, options);
var tracedata = void 0;
if (options.layering === 0) {
tracedata = {
layers: [],
palette: ii.palette,
width: ii.array[0].length - 2,
height: ii.array.length - 2
};
for (var colornum = 0; colornum < ii.palette.length; colornum += 1) {
var tracedlayer = this.batchtracepaths(this.internodes(this.pathscan(this.layeringstep(ii, colornum), options.pathomit), options), options.ltres, options.qtres);
tracedata.layers.push(tracedlayer);
}
} else {
var ls = this.layering(ii);
if (options.layercontainerid) {
this.drawLayers(ls, this.specpalette, options.scale, options.layercontainerid);
}
var bps = this.batchpathscan(ls, options.pathomit);
var bis = this.batchinternodes(bps, options);
tracedata = {
layers: this.batchtracelayers(bis, options.ltres, options.qtres),
palette: ii.palette,
width: imgd.width,
height: imgd.height
};
}
return tracedata;
}
}, {
key: 'checkoptions',
value: function checkoptions(options) {
options = options || {};
if (typeof options === 'string') {
options = options.toLowerCase();
if (this.optionpresets[options]) {
options = this.optionpresets[options];
} else {
options = {};
}
}
var ok = Object.keys(this.optionpresets['default']);
for (var k = 0; k < ok.length; k += 1) {
if (!options.hasOwnProperty(ok[k])) {
options[ok[k]] = this.optionpresets['default'][ok[k]];
}
}
return options;
}
}, {
key: 'colorquantization',
value: function colorquantization(imgd, options) {
var arr = [];
var idx = 0;
var cd = void 0;
var cdl = void 0;
var ci = void 0;
var paletteacc = [];
var pixelnum = imgd.width * imgd.height;
var i = void 0;
var j = void 0;
var k = void 0;
var cnt = void 0;
var palette = void 0;
for (j = 0; j < imgd.height + 2; j += 1) {
arr[j] = [];
for (i = 0; i < imgd.width + 2; i += 1) {
arr[j][i] = -1;
}
}
if (options.pal) {
palette = options.pal;
} else if (options.colorsampling === 0) {
palette = this.generatepalette(options.numberofcolors);
} else if (options.colorsampling === 1) {
palette = this.samplepalette(options.numberofcolors, imgd);
} else {
palette = this.samplepalette2(options.numberofcolors, imgd);
}
if (options.blurradius > 0) {
imgd = this.blur(imgd, options.blurradius, options.blurdelta);
}
for (cnt = 0; cnt < options.colorquantcycles; cnt += 1) {
if (cnt > 0) {
for (k = 0; k < palette.length; k += 1) {
if (paletteacc[k].n > 0) {
palette[k] = { r: Math.floor(paletteacc[k].r / paletteacc[k].n),
g: Math.floor(paletteacc[k].g / paletteacc[k].n),
b: Math.floor(paletteacc[k].b / paletteacc[k].n),
a: Math.floor(paletteacc[k].a / paletteacc[k].n) };
}
if (paletteacc[k].n / pixelnum < options.mincolorratio && cnt < options.colorquantcycles - 1) {
palette[k] = { r: Math.floor(Math.random() * 255),
g: Math.floor(Math.random() * 255),
b: Math.floor(Math.random() * 255),
a: Math.floor(Math.random() * 255) };
}
}
}
for (i = 0; i < palette.length; i += 1) {
paletteacc[i] = { r: 0,
g: 0,
b: 0,
a: 0,
n: 0 };
}
for (j = 0; j < imgd.height; j += 1) {
for (i = 0; i < imgd.width; i += 1) {
idx = (j * imgd.width + i) * 4;
ci = 0;
cdl = 1024;
for (k = 0; k < palette.length; k += 1) {
cd = Math.abs(palette[k].r - imgd.data[idx]) + Math.abs(palette[k].g - imgd.data[idx + 1]) + Math.abs(palette[k].b - imgd.data[idx + 2]) + Math.abs(palette[k].a - imgd.data[idx + 3]);
if (cd < cdl) {
cdl = cd;
ci = k;
}
}
paletteacc[ci].r += imgd.data[idx];
paletteacc[ci].g += imgd.data[idx + 1];
paletteacc[ci].b += imgd.data[idx + 2];
paletteacc[ci].a += imgd.data[idx + 3];
paletteacc[ci].n += 1;
arr[j + 1][i + 1] = ci;
}
}
}
return { array: arr,
palette: palette };
}
}, {
key: 'samplepalette',
value: function samplepalette(numberofcolors, imgd) {
var idx = void 0;
var palette = [];
for (var i = 0; i < numberofcolors; i += 1) {
idx = Math.floor(Math.random() * imgd.data.length / 4) * 4;
palette.push({ r: imgd.data[idx],
g: imgd.data[idx + 1],
b: imgd.data[idx + 2],
a: imgd.data[idx + 3] });
}
return palette;
}
}, {
key: 'samplepalette2',
value: function samplepalette2(numberofcolors, imgd) {
var idx = void 0;
var palette = [];
var ni = Math.ceil(Math.sqrt(numberofcolors));
var nj = Math.ceil(numberofcolors / ni);
var vx = imgd.width / (ni + 1);
var vy = imgd.height / (nj + 1);
for (var j = 0; j < nj; j += 1) {
for (var i = 0; i < ni; i += 1) {
if (palette.length === numberofcolors) {
break;
} else {
idx = Math.floor((j + 1) * vy * imgd.width + (i + 1) * vx) * 4;
palette.push({ r: imgd.data[idx],
g: imgd.data[idx + 1],
b: imgd.data[idx + 2],
a: imgd.data[idx + 3] });
}
}
}
return palette;
}
}, {
key: 'generatepalette',
value: function generatepalette(numberofcolors) {
var palette = [];
var rcnt = void 0;
var gcnt = void 0;
var bcnt = void 0;
if (numberofcolors < 8) {
var graystep = Math.floor(255 / (numberofcolors - 1));
for (var i = 0; i < numberofcolors; i += 1) {
palette.push({ r: i * graystep,
g: i * graystep,
b: i * graystep,
a: 255 });
}
} else {
var colorqnum = Math.floor(Math.pow(numberofcolors, 1 / 3));
var colorstep = Math.floor(255 / (colorqnum - 1));
var rndnum = numberofcolors - colorqnum * colorqnum * colorqnum;
for (rcnt = 0; rcnt < colorqnum; rcnt += 1) {
for (gcnt = 0; gcnt < colorqnum; gcnt += 1) {
for (bcnt = 0; bcnt < colorqnum; bcnt += 1) {
palette.push({ r: rcnt * colorstep,
g: gcnt * colorstep,
b: bcnt * colorstep,
a: 255 });
}
}
}
for (rcnt = 0; rcnt < rndnum; rcnt += 1) {
palette.push({ r: Math.floor(Math.random() * 255),
g: Math.floor(Math.random() * 255),
b: Math.floor(Math.random() * 255),
a: Math.floor(Math.random() * 255) });
}
}
return palette;
}
}, {
key: 'layering',
value: function layering(ii) {
var layers = [];
var val = 0;
var ah = ii.array.length;
var aw = ii.array[0].length;
var n1 = void 0;
var n2 = void 0;
var n3 = void 0;
var n4 = void 0;
var n5 = void 0;
var n6 = void 0;
var n7 = void 0;
var n8 = void 0;
var i = void 0;
var j = void 0;
var k = void 0;
for (k = 0; k < ii.palette.length; k += 1) {
layers[k] = [];
for (j = 0; j < ah; j += 1) {
layers[k][j] = [];
for (i = 0; i < aw; i += 1) {
layers[k][j][i] = 0;
}
}
}
for (j = 1; j < ah - 1; j += 1) {
for (i = 1; i < aw - 1; i += 1) {
val = ii.array[j][i];
n1 = ii.array[j - 1][i - 1] === val ? 1 : 0;
n2 = ii.array[j - 1][i] === val ? 1 : 0;
n3 = ii.array[j - 1][i + 1] === val ? 1 : 0;
n4 = ii.array[j][i - 1] === val ? 1 : 0;
n5 = ii.array[j][i + 1] === val ? 1 : 0;
n6 = ii.array[j + 1][i - 1] === val ? 1 : 0;
n7 = ii.array[j + 1][i] === val ? 1 : 0;
n8 = ii.array[j + 1][i + 1] === val ? 1 : 0;
layers[val][j + 1][i + 1] = 1 + n5 * 2 + n8 * 4 + n7 * 8;
if (!n4) {
layers[val][j + 1][i] = 0 + 2 + n7 * 4 + n6 * 8;
}
if (!n2) {
layers[val][j][i + 1] = 0 + n3 * 2 + n5 * 4 + 8;
}
if (!n1) {
layers[val][j][i] = 0 + n2 * 2 + 4 + n4 * 8;
}
}
}
return layers;
}
}, {
key: 'layeringstep',
value: function layeringstep(ii, cnum) {
var layer = [];
var ah = ii.array.length;
var aw = ii.array[0].length;
var i = void 0;
var j = void 0;
for (j = 0; j < ah; j += 1) {
layer[j] = [];
for (i = 0; i < aw; i += 1) {
layer[j][i] = 0;
}
}
for (j = 1; j < ah; j += 1) {
for (i = 1; i < aw; i += 1) {
layer[j][i] = (ii.array[j - 1][i - 1] === cnum ? 1 : 0) + (ii.array[j - 1][i] === cnum ? 2 : 0) + (ii.array[j][i - 1] === cnum ? 8 : 0) + (ii.array[j][i] === cnum ? 4 : 0);
}
}
return layer;
}
}, {
key: 'pathscan',
value: function pathscan(arr, pathomit) {
var paths = [];
var pacnt = 0;
var pcnt = 0;
var px = 0;
var py = 0;
var w = arr[0].length;
var h = arr.length;
var dir = 0;
var pathfinished = true;
var holepath = false;
var lookuprow = void 0;
for (var j = 0; j < h; j += 1) {
for (var i = 0; i < w; i += 1) {
if (arr[j][i] === 4 || arr[j][i] === 11) {
px = i;
py = j;
paths[pacnt] = {};
paths[pacnt].points = [];
paths[pacnt].boundingbox = [px, py, px, py];
paths[pacnt].holechildren = [];
pathfinished = false;
pcnt = 0;
holepath = arr[j][i] === 11;
dir = 1;
while (!pathfinished) {
paths[pacnt].points[pcnt] = {};
paths[pacnt].points[pcnt].x = px - 1;
paths[pacnt].points[pcnt].y = py - 1;
paths[pacnt].points[pcnt].t = arr[py][px];
if (px - 1 < paths[pacnt].boundingbox[0]) {
paths[pacnt].boundingbox[0] = px - 1;
}
if (px - 1 > paths[pacnt].boundingbox[2]) {
paths[pacnt].boundingbox[2] = px - 1;
}
if (py - 1 < paths[pacnt].boundingbox[1]) {
paths[pacnt].boundingbox[1] = py - 1;
}
if (py - 1 > paths[pacnt].boundingbox[3]) {
paths[pacnt].boundingbox[3] = py - 1;
}
lookuprow = this.pathscan_combined_lookup[arr[py][px]][dir];
arr[py][px] = lookuprow[0];dir = lookuprow[1];px += lookuprow[2];py += lookuprow[3];
if (px - 1 === paths[pacnt].points[0].x && py - 1 === paths[pacnt].points[0].y) {
pathfinished = true;
if (paths[pacnt].points.length < pathomit) {
paths.pop();
} else {
paths[pacnt].isholepath = !!holepath;
if (holepath) {
var parentidx = 0,
parentbbox = [-1, -1, w + 1, h + 1];
for (var parentcnt = 0; parentcnt < pacnt; parentcnt++) {
if (!paths[parentcnt].isholepath && this.boundingboxincludes(paths[parentcnt].boundingbox, paths[pacnt].boundingbox) && this.boundingboxincludes(parentbbox, paths[parentcnt].boundingbox)) {
parentidx = parentcnt;
parentbbox = paths[parentcnt].boundingbox;
}
}
paths[parentidx].holechildren.push(pacnt);
}
pacnt += 1;
}
}
pcnt += 1;
}
}
}
}
return paths;
}
}, {
key: 'boundingboxincludes',
value: function boundingboxincludes(parentbbox, childbbox) {
return parentbbox[0] < childbbox[0] && parentbbox[1] < childbbox[1] && parentbbox[2] > childbbox[2] && parentbbox[3] > childbbox[3];
}
}, {
key: 'batchpathscan',
value: function batchpathscan(layers, pathomit) {
var bpaths = [];
for (var k in layers) {
if (!layers.hasOwnProperty(k)) {
continue;
}
bpaths[k] = this.pathscan(layers[k], pathomit);
}
return bpaths;
}
}, {
key: 'internodes',
value: function internodes(paths, options) {
var ins = [];
var palen = 0;
var nextidx = 0;
var nextidx2 = 0;
var previdx = 0;
var previdx2 = 0;
var pacnt = void 0;
var pcnt = void 0;
for (pacnt = 0; pacnt < paths.length; pacnt += 1) {
ins[pacnt] = {};
ins[pacnt].points = [];
ins[pacnt].boundingbox = paths[pacnt].boundingbox;
ins[pacnt].holechildren = paths[pacnt].holechildren;
ins[pacnt].isholepath = paths[pacnt].isholepath;
palen = paths[pacnt].points.length;
for (pcnt = 0; pcnt < palen; pcnt += 1) {
nextidx = (pcnt + 1) % palen;nextidx2 = (pcnt + 2) % palen;previdx = (pcnt - 1 + palen) % palen;previdx2 = (pcnt - 2 + palen) % palen;
if (options.rightangleenhance && this.testrightangle(paths[pacnt], previdx2, previdx, pcnt, nextidx, nextidx2)) {
if (ins[pacnt].points.length > 0) {
ins[pacnt].points[ins[pacnt].points.length - 1].linesegment = this.getdirection(ins[pacnt].points[ins[pacnt].points.length - 1].x, ins[pacnt].points[ins[pacnt].points.length - 1].y, paths[pacnt].points[pcnt].x, paths[pacnt].points[pcnt].y);
}
ins[pacnt].points.push({
x: paths[pacnt].points[pcnt].x,
y: paths[pacnt].points[pcnt].y,
linesegment: this.getdirection(paths[pacnt].points[pcnt].x, paths[pacnt].points[pcnt].y, (paths[pacnt].points[pcnt].x + paths[pacnt].points[nextidx].x) / 2, (paths[pacnt].points[pcnt].y + paths[pacnt].points[nextidx].y) / 2)
});
}
ins[pacnt].points.push({
x: (paths[pacnt].points[pcnt].x + paths[pacnt].points[nextidx].x) / 2,
y: (paths[pacnt].points[pcnt].y + paths[pacnt].points[nextidx].y) / 2,
linesegment: this.getdirection((paths[pacnt].points[pcnt].x + paths[pacnt].points[nextidx].x) / 2, (paths[pacnt].points[pcnt].y + paths[pacnt].points[nextidx].y) / 2, (paths[pacnt].points[nextidx].x + paths[pacnt].points[nextidx2].x) / 2, (paths[pacnt].points[nextidx].y + paths[pacnt].points[nextidx2].y) / 2)
});
}
}
return ins;
}
}, {
key: 'testrightangle',
value: function testrightangle(path, idx1, idx2, idx3, idx4, idx5) {
return path.points[idx3].x === path.points[idx1].x && path.points[idx3].x === path.points[idx2].x && path.points[idx3].y === path.points[idx4].y && path.points[idx3].y === path.points[idx5].y || path.points[idx3].y === path.points[idx1].y && path.points[idx3].y === path.points[idx2].y && path.points[idx3].x === path.points[idx4].x && path.points[idx3].x === path.points[idx5].x;
}
}, {
key: 'getdirection',
value: function getdirection(x1, y1, x2, y2) {
var val = 8;
if (x1 < x2) {
if (y1 < y2) {
val = 1;
} else if (y1 > y2) {
val = 7;
} else {
val = 0;
}
} else if (x1 > x2) {
if (y1 < y2) {
val = 3;
} else if (y1 > y2) {
val = 5;
} else {
val = 4;
}
} else if (y1 < y2) {
val = 2;
} else if (y1 > y2) {
val = 6;
} else {
val = 8;
}
return val;
}
}, {
key: 'batchinternodes',
value: function batchinternodes(bpaths, options) {
var binternodes = [];
for (var k in bpaths) {
if (!bpaths.hasOwnProperty(k)) {
continue;
}
binternodes[k] = this.internodes(bpaths[k], options);
}
return binternodes;
}
}, {
key: 'tracepath',
value: function tracepath(path, ltres, qtres) {
var pcnt = 0;
var segtype1 = void 0;
var segtype2 = void 0;
var seqend = void 0;
var smp = {};
smp.segments = [];
smp.boundingbox = path.boundingbox;
smp.holechildren = path.holechildren;
smp.isholepath = path.isholepath;
while (pcnt < path.points.length) {
segtype1 = path.points[pcnt].linesegment;
segtype2 = -1;
seqend = pcnt + 1;
while ((path.points[seqend].linesegment === segtype1 || path.points[seqend].linesegment === segtype2 || segtype2 === -1) && seqend < path.points.length - 1) {
if (path.points[seqend].linesegment !== segtype1 && segtype2 === -1) {
segtype2 = path.points[seqend].linesegment;
}
seqend += 1;
}
if (seqend === path.points.length - 1) {
seqend = 0;
}
smp.segments = smp.segments.concat(this.fitseq(path, ltres, qtres, pcnt, seqend));
if (seqend > 0) {
pcnt = seqend;
} else {
pcnt = path.points.length;
}
}
return smp;
}
}, {
key: 'fitseq',
value: function fitseq(path, ltres, qtres, seqstart, seqend) {
if (seqend > path.points.length || seqend < 0) {
return [];
}
var errorpoint = seqstart,
errorval = 0,
curvepass = true,
px = void 0,
py = void 0,
dist2 = void 0;
var tl = seqend - seqstart;if (tl < 0) {
tl += path.points.length;
}
var vx = (path.points[seqend].x - path.points[seqstart].x) / tl,
vy = (path.points[seqend].y - path.points[seqstart].y) / tl;
var pcnt = (seqstart + 1) % path.points.length,
pl = void 0;
while (pcnt != seqend) {
pl = pcnt - seqstart;if (pl < 0) {
pl += path.points.length;
}
px = path.points[seqstart].x + vx * pl;py = path.points[seqstart].y + vy * pl;
dist2 = (path.points[pcnt].x - px) * (path.points[pcnt].x - px) + (path.points[pcnt].y - py) * (path.points[pcnt].y - py);
if (dist2 > ltres) {
curvepass = false;
}
if (dist2 > errorval) {
errorpoint = pcnt;errorval = dist2;
}
pcnt = (pcnt + 1) % path.points.length;
}
if (curvepass) {
return [{ type: 'L',
x1: path.points[seqstart].x,
y1: path.points[seqstart].y,
x2: path.points[seqend].x,
y2: path.points[seqend].y }];
}
var fitpoint = errorpoint;curvepass = true;errorval = 0;
var t = (fitpoint - seqstart) / tl,
t1 = (1 - t) * (1 - t),
t2 = 2 * (1 - t) * t,
t3 = t * t;
var cpx = (t1 * path.points[seqstart].x + t3 * path.points[seqend].x - path.points[fitpoint].x) / -t2,
cpy = (t1 * path.points[seqstart].y + t3 * path.points[seqend].y - path.points[fitpoint].y) / -t2;
pcnt = seqstart + 1;
while (pcnt != seqend) {
t = (pcnt - seqstart) / tl;t1 = (1 - t) * (1 - t);t2 = 2 * (1 - t) * t;t3 = t * t;
px = t1 * path.points[seqstart].x + t2 * cpx + t3 * path.points[seqend].x;
py = t1 * path.points[seqstart].y + t2 * cpy + t3 * path.points[seqend].y;
dist2 = (path.points[pcnt].x - px) * (path.points[pcnt].x - px) + (path.points[pcnt].y - py) * (path.points[pcnt].y - py);
if (dist2 > qtres) {
curvepass = false;
}
if (dist2 > errorval) {
errorpoint = pcnt;errorval = dist2;
}
pcnt = (pcnt + 1) % path.points.length;
}
if (curvepass) {
return [{ type: 'Q',
x1: path.points[seqstart].x,
y1: path.points[seqstart].y,
x2: cpx,
y2: cpy,
x3: path.points[seqend].x,
y3: path.points[seqend].y }];
}
var splitpoint = fitpoint;
return this.fitseq(path, ltres, qtres, seqstart, splitpoint).concat(this.fitseq(path, ltres, qtres, splitpoint, seqend));
}
}, {
key: 'batchtracepaths',
value: function batchtracepaths(internodepaths, ltres, qtres) {
var btracedpaths = [];
for (var k in internodepaths) {
if (!internodepaths.hasOwnProperty(k)) {
continue;
}
btracedpaths.push(this.tracepath(internodepaths[k], ltres, qtres));
}
return btracedpaths;
}
}, {
key: 'batchtracelayers',
value: function batchtracelayers(binternodes, ltres, qtres) {
var btbis = [];
for (var k in binternodes) {
if (!binternodes.hasOwnProperty(k)) {
continue;
}
btbis[k] = this.batchtracepaths(binternodes[k], ltres, qtres);
}
return btbis;
}
}, {
key: 'roundtodec',
value: function roundtodec(val, places) {
return Number(val.toFixed(places));
}
}, {
key: 'svgpathstring',
value: function svgpathstring(tracedata, lnum, pathnum, options) {
var layer = tracedata.layers[lnum],
smp = layer[pathnum],
str = '',
pcnt = void 0;
if (options.linefilter && smp.segments.length < 3) {
return str;
}
str = '<path ' + (options.desc ? 'desc="l ' + lnum + ' p ' + pathnum + '" ' : '') + this.tosvgcolorstr(tracedata.palette[lnum], options) + 'd="';
if (options.roundcoords === -1) {
str += 'M ' + smp.segments[0].x1 * options.scale + ' ' + smp.segments[0].y1 * options.scale + ' ';
for (pcnt = 0; pcnt < smp.segments.length; pcnt++) {
str += smp.segments[pcnt].type + ' ' + smp.segments[pcnt].x2 * options.scale + ' ' + smp.segments[pcnt].y2 * options.scale + ' ';
if (smp.segments[pcnt].hasOwnProperty('x3')) {
str += smp.segments[pcnt].x3 * options.scale + ' ' + smp.segments[pcnt].y3 * options.scale + ' ';
}
}
str += 'Z ';
} else {
str += 'M ' + this.roundtodec(smp.segments[0].x1 * options.scale, options.roundcoords) + ' ' + this.roundtodec(smp.segments[0].y1 * options.scale, options.roundcoords) + ' ';
for (pcnt = 0; pcnt < smp.segments.length; pcnt++) {
str += smp.segments[pcnt].type + ' ' + this.roundtodec(smp.segments[pcnt].x2 * options.scale, options.roundcoords) + ' ' + this.roundtodec(smp.segments[pcnt].y2 * options.scale, options.roundcoords) + ' ';
if (smp.segments[pcnt].hasOwnProperty('x3')) {
str += this.roundtodec(smp.segments[pcnt].x3 * options.scale, options.roundcoords) + ' ' + this.roundtodec(smp.segments[pcnt].y3 * options.scale, options.roundcoords) + ' ';
}
}
str += 'Z ';
}
for (var hcnt = 0; hcnt < smp.holechildren.length; hcnt++) {
var hsmp = layer[smp.holechildren[hcnt]];
if (options.roundcoords === -1) {
if (hsmp.segments[hsmp.segments.length - 1].hasOwnProperty('x3')) {
str += 'M ' + hsmp.segments[hsmp.segments.length - 1].x3 * options.scale + ' ' + hsmp.segments[hsmp.segments.length - 1].y3 * options.scale + ' ';
} else {
str += 'M ' + hsmp.segments[hsmp.segments.length - 1].x2 * options.scale + ' ' + hsmp.segments[hsmp.segments.length - 1].y2 * options.scale + ' ';
}
for (pcnt = hsmp.segments.length - 1; pcnt >= 0; pcnt--) {
str += hsmp.segments[pcnt].type + ' ';
if (hsmp.segments[pcnt].hasOwnProperty('x3')) {
str += hsmp.segments[pcnt].x2 * options.scale + ' ' + hsmp.segments[pcnt].y2 * options.scale + ' ';
}
str += hsmp.segments[pcnt].x1 * options.scale + ' ' + hsmp.segments[pcnt].y1 * options.scale + ' ';
}
} else {
if (hsmp.segments[hsmp.segments.length - 1].hasOwnProperty('x3')) {
str += 'M ' + this.roundtodec(hsmp.segments[hsmp.segments.length - 1].x3 * options.scale) + ' ' + this.roundtodec(hsmp.segments[hsmp.segments.length - 1].y3 * options.scale) + ' ';
} else {
str += 'M ' + this.roundtodec(hsmp.segments[hsmp.segments.length - 1].x2 * options.scale) + ' ' + this.roundtodec(hsmp.segments[hsmp.segments.length - 1].y2 * options.scale) + ' ';
}
for (pcnt = hsmp.segments.length - 1; pcnt >= 0; pcnt--) {
str += hsmp.segments[pcnt].type + ' ';
if (hsmp.segments[pcnt].hasOwnProperty('x3')) {
str += this.roundtodec(hsmp.segments[pcnt].x2 * options.scale) + ' ' + this.roundtodec(hsmp.segments[pcnt].y2 * options.scale) + ' ';
}
str += this.roundtodec(hsmp.segments[pcnt].x1 * options.scale) + ' ' + this.roundtodec(hsmp.segments[pcnt].y1 * options.scale) + ' ';
}
}
str += 'Z ';
}
str += '" />';
if (options.lcpr || options.qcpr) {
for (pcnt = 0; pcnt < smp.segments.length; pcnt++) {
if (smp.segments[pcnt].hasOwnProperty('x3') && options.qcpr) {
str += '<circle cx="' + smp.segments[pcnt].x2 * options.scale + '" cy="' + smp.segments[pcnt].y2 * options.scale + '" r="' + options.qcpr + '" fill="cyan" stroke-width="' + options.qcpr * 0.2 + '" stroke="black" />';
str += '<circle cx="' + smp.segments[pcnt].x3 * options.scale + '" cy="' + smp.segments[pcnt].y3 * options.scale + '" r="' + options.qcpr + '" fill="white" stroke-width="' + options.qcpr * 0.2 + '" stroke="black" />';
str += '<line x1="' + smp.segments[pcnt].x1 * options.scale + '" y1="' + smp.segments[pcnt].y1 * options.scale + '" x2="' + smp.segments[pcnt].x2 * options.scale + '" y2="' + smp.segments[pcnt].y2 * options.scale + '" stroke-width="' + options.qcpr * 0.2 + '" stroke="cyan" />';
str += '<line x1="' + smp.segments[pcnt].x2 * options.scale + '" y1="' + smp.segments[pcnt].y2 * options.scale + '" x2="' + smp.segments[pcnt].x3 * options.scale + '" y2="' + smp.segments[pcnt].y3 * options.scale + '" stroke-width="' + options.qcpr * 0.2 + '" stroke="cyan" />';
}
if (!smp.segments[pcnt].hasOwnProperty('x3') && options.lcpr) {
str += '<circle cx="' + smp.segments[pcnt].x2 * options.scale + '" cy="' + smp.segments[pcnt].y2 * options.scale + '" r="' + options.lcpr + '" fill="white" stroke-width="' + options.lcpr * 0.2 + '" stroke="black" />';
}
}
for (var hcnt = 0; hcnt < smp.holechildren.length; hcnt++) {
var hsmp = layer[smp.holechildren[hcnt]];
for (pcnt = 0; pcnt < hsmp.segments.length; pcnt++) {
if (hsmp.segments[pcnt].hasOwnProperty('x3') && options.qcpr) {
str += '<circle cx="' + hsmp.segments[pcnt].x2 * options.scale + '" cy="' + hsmp.segments[pcnt].y2 * options.scale + '" r="' + options.qcpr + '" fill="cyan" stroke-width="' + options.qcpr * 0.2 + '" stroke="black" />';
str += '<circle cx="' + hsmp.segments[pcnt].x3 * options.scale + '" cy="' + hsmp.segments[pcnt].y3 * options.scale + '" r="' + options.qcpr + '" fill="white" stroke-width="' + options.qcpr * 0.2 + '" stroke="black" />';
str += '<line x1="' + hsmp.segments[pcnt].x1 * options.scale + '" y1="' + hsmp.segments[pcnt].y1 * options.scale + '" x2="' + hsmp.segments[pcnt].x2 * options.scale + '" y2="' + hsmp.segments[pcnt].y2 * options.scale + '" stroke-width="' + options.qcpr * 0.2 + '" stroke="cyan" />';
str += '<line x1="' + hsmp.segments[pcnt].x2 * options.scale + '" y1="' + hsmp.segments[pcnt].y2 * options.scale + '" x2="' + hsmp.segments[pcnt].x3 * options.scale + '" y2="' + hsmp.segments[pcnt].y3 * options.scale + '" stroke-width="' + options.qcpr * 0.2 + '" stroke="cyan" />';
}
if (!hsmp.segments[pcnt].hasOwnProperty('x3') && options.lcpr) {
str += '<circle cx="' + hsmp.segments[pcnt].x2 * options.scale + '" cy="' + hsmp.segments[pcnt].y2 * options.scale + '" r="' + options.lcpr + '" fill="white" stroke-width="' + options.lcpr * 0.2 + '" stroke="black" />';
}
}
}
}
return str;
}
}, {
key: 'getsvgstring',
value: function getsvgstring(tracedata, options) {
options = this.checkoptions(options);
var w = tracedata.width * options.scale;
var h = tracedata.height * options.scale;
var svgstr = '<svg ' + (options.viewbox ? 'viewBox="0 0 ' + w + ' ' + h + '" ' : 'width="' + w + '" height="' + h + '" ') + 'version="1.1" xmlns="http://www.w3.org/2000/svg" desc="Created with imagetracer.js version ' + this.versionnumber + '" >';
for (var lcnt = 0; lcnt < tracedata.layers.length; lcnt += 1) {
for (var pcnt = 0; pcnt < tracedata.layers[lcnt].length; pcnt += 1) {
if (!tracedata.layers[lcnt][pcnt].isholepath) {
svgstr += this.svgpathstring(tracedata, lcnt, pcnt, options);
}
}
}
svgstr += '</svg>';
return svgstr;
}
}, {
key: 'compareNumbers',
value: function compareNumbers(a, b) {
return a - b;
}
}, {
key: 'torgbastr',
value: function torgbastr(c) {
return 'rgba(' + c.r + ',' + c.g + ',' + c.b + ',' + c.a + ')';
}
}, {
key: 'tosvgcolorstr',
value: function tosvgcolorstr(c, options) {
return 'fill="rgb(' + c.r + ',' + c.g + ',' + c.b + ')" stroke="rgb(' + c.r + ',' + c.g + ',' + c.b + ')" stroke-width="' + options.strokewidth + '" opacity="' + c.a / 255.0 + '" ';
}
}, {
key: 'appendSVGString',
value: function appendSVGString(svgstr, parentid) {
var div = void 0;
if (parentid) {
div = document.getElementById(parentid);
if (!div) {
div = document.createElement('div');
div.id = parentid;
document.body.appendChild(div);
}
} else {
div = document.createElement('div');
document.body.appendChild(div);
}
div.innerHTML += svgstr;
}
}, {
key: 'blur',
value: function blur(imgd, radius, delta) {
var i = void 0,
j = void 0,
k = void 0,
d = void 0,
idx = void 0,
racc = void 0,
gacc = void 0,
bacc = void 0,
aacc = void 0,
wacc = void 0;
var imgd2 = { width: imgd.width,
height: imgd.height,
data: [] };
radius = Math.floor(radius);if (radius < 1) {
return imgd;
}if (radius > 5) {
radius = 5;
}delta = Math.abs(delta);if (delta > 1024) {
delta = 1024;
}
var thisgk = this.gks[radius - 1];
for (j = 0; j < imgd.height; j++) {
for (i = 0; i < imgd.width; i++) {
racc = 0;gacc = 0;bacc = 0;aacc = 0;wacc = 0;
for (k = -radius; k < radius + 1; k++) {
if (i + k > 0 && i + k < imgd.width) {
idx = (j * imgd.width + i + k) * 4;
racc += imgd.data[idx] * thisgk[k + radius];
gacc += imgd.data[idx + 1] * thisgk[k + radius];
bacc += imgd.data[idx + 2] * thisgk[k + radius];
aacc += imgd.data[idx + 3] * thisgk[k + radius];
wacc += thisgk[k + radius];
}
}
idx = (j * imgd.width + i) * 4;
imgd2.data[idx] = Math.floor(racc / wacc);
imgd2.data[idx + 1] = Math.floor(gacc / wacc);
imgd2.data[idx + 2] = Math.floor(bacc / wacc);
imgd2.data[idx + 3] = Math.floor(aacc / wacc);
}
}
var himgd = new Uint8ClampedArray(imgd2.data);
for (j = 0; j < imgd.height; j++) {
for (i = 0; i < imgd.width; i++) {
racc = 0;gacc = 0;bacc = 0;aacc = 0;wacc = 0;
for (k = -radius; k < radius + 1; k++) {
if (j + k > 0 && j + k < imgd.height) {
idx = ((j + k) * imgd.width + i) * 4;
racc += himgd[idx] * thisgk[k + radius];
gacc += himgd[idx + 1] * thisgk[k + radius];
bacc += himgd[idx + 2] * thisgk[k + radius];
aacc += himgd[idx + 3] * thisgk[k + radius];
wacc += thisgk[k + radius];
}
}
idx = (j * imgd.width + i) * 4;
imgd2.data[idx] = Math.floor(racc / wacc);
imgd2.data[idx + 1] = Math.floor(gacc / wacc);
imgd2.data[idx + 2] = Math.floor(bacc / wacc);
imgd2.data[idx + 3] = Math.floor(aacc / wacc);
}
}
for (j = 0; j < imgd.height; j++) {
for (i = 0; i < imgd.width; i++) {
idx = (j * imgd.width + i) * 4;
d = Math.abs(imgd2.data[idx] - imgd.data[idx]) + Math.abs(imgd2.data[idx + 1] - imgd.data[idx + 1]) + Math.abs(imgd2.data[idx + 2] - imgd.data[idx + 2]) + Math.abs(imgd2.data[idx + 3] - imgd.data[idx + 3]);
if (d > delta) {
imgd2.data[idx] = imgd.data[idx];
imgd2.data[idx + 1] = imgd.data[idx + 1];
imgd2.data[idx + 2] = imgd.data[idx + 2];
imgd2.data[idx + 3] = imgd.data[idx + 3];
}
}
}
return imgd2;
}
}, {
key: 'loadImage',
value: function loadImage(url, callback, options) {
var img = new Image();
if (options && options.corsenabled) {
img.crossOrigin = 'Anonymous';
}
img.src = url;
img.onload = function () {
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
callback(canvas);
};
}
}, {
key: 'getImgdata',
value: function getImgdata(canvas) {
var context = canvas.getContext('2d');
return context.getImageData(0, 0, canvas.width, canvas.height);
}
}, {
key: 'drawLayers',
value: function drawLayers(layers, palette, scale, parentid) {
scale = scale || 1;
var w = void 0,
h = void 0,
i = void 0,
j = void 0,
k = void 0;
var div = void 0;
if (parentid) {
div = document.getElementById(parentid);
if (!div) {
div = document.createElement('div');
div.id = parentid;
document.body.appendChild(div);
}
} else {
div = document.createElement('div');
document.body.appendChild(div);
}
for (k in layers) {
if (!layers.hasOwnProperty(k)) {
continue;
}
w = layers[k][0].length;
h = layers[k].length;
var canvas = document.createElement('canvas');
canvas.width = w * scale;
canvas.height = h * scale;
var context = canvas.getContext('2d');
for (j = 0; j < h; j += 1) {
for (i = 0; i < w; i += 1) {
context.fillStyle = this.torgbastr(palette[layers[k][j][i] % palette.length]);
context.fillRect(i * scale, j * scale, scale, scale);
}
}
div.appendChild(canvas);
}
}
}]);
return ImageTracer;
}();
exports.default = ImageTracer;
/***/ }),
/* 104 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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; }; }(); /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Graphics module
*/
var _tuiCodeSnippet = __webpack_require__(3);
var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _fabric = __webpack_require__(105);
var _fabric2 = _interopRequireDefault(_fabric);
var _imageLoader = __webpack_require__(150);
var _imageLoader2 = _interopRequireDefault(_imageLoader);
var _cropper = __webpack_require__(152);
var _cropper2 = _interopRequireDefault(_cropper);
var _flip = __webpack_require__(154);
var _flip2 = _interopRequireDefault(_flip);
var _rotation = __webpack_require__(155);
var _rotation2 = _interopRequireDefault(_rotation);
var _freeDrawing = __webpack_require__(156);
var _freeDrawing2 = _interopRequireDefault(_freeDrawing);
var _line = __webpack_require__(157);
var _line2 = _interopRequireDefault(_line);
var _text = __webpack_require__(158);
var _text2 = _interopRequireDefault(_text);
var _icon = __webpack_require__(159);
var _icon2 = _interopRequireDefault(_icon);
var _filter = __webpack_require__(160);
var _filter2 = _interopRequireDefault(_filter);
var _shape = __webpack_require__(167);
var _shape2 = _interopRequireDefault(_shape);
var _cropper3 = __webpack_require__(169);
var _cropper4 = _interopRequireDefault(_cropper3);
var _freeDrawing3 = __webpack_require__(171);
var _freeDrawing4 = _interopRequireDefault(_freeDrawing3);
var _lineDrawing = __webpack_require__(172);
var _lineDrawing2 = _interopRequireDefault(_lineDrawing);
var _shape3 = __webpack_require__(173);
var _shape4 = _interopRequireDefault(_shape3);
var _text3 = __webpack_require__(174);
var _text4 = _interopRequireDefault(_text3);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
var _util = __webpack_require__(72);
var _util2 = _interopRequireDefault(_util);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var components = _consts2.default.componentNames;
var events = _consts2.default.eventNames;
var drawingModes = _consts2.default.drawingModes,
fObjectOptions = _consts2.default.fObjectOptions;
var extend = _tuiCodeSnippet2.default.extend,
stamp = _tuiCodeSnippet2.default.stamp,
isArray = _tuiCodeSnippet2.default.isArray,
isString = _tuiCodeSnippet2.default.isString,
forEachArray = _tuiCodeSnippet2.default.forEachArray,
forEachOwnProperties = _tuiCodeSnippet2.default.forEachOwnProperties,
CustomEvents = _tuiCodeSnippet2.default.CustomEvents;
var DEFAULT_CSS_MAX_WIDTH = 1000;
var DEFAULT_CSS_MAX_HEIGHT = 800;
var cssOnly = {
cssOnly: true
};
var backstoreOnly = {
backstoreOnly: true
};
/**
* Graphics class
* @class
* @param {string|jQuery|HTMLElement} wrapper - Wrapper's element or selector
* @param {Object} [option] - Canvas max width & height of css
* @param {number} option.cssMaxWidth - Canvas css-max-width
* @param {number} option.cssMaxHeight - Canvas css-max-height
* @param {boolean} option.useItext - Use IText in text mode
* @param {boolean} option.useDragAddIcon - Use dragable add in icon mode
* @ignore
*/
var Graphics = function () {
function Graphics(element) {
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
cssMaxWidth = _ref.cssMaxWidth,
cssMaxHeight = _ref.cssMaxHeight,
_ref$useItext = _ref.useItext,
useItext = _ref$useItext === undefined ? false : _ref$useItext,
_ref$useDragAddIcon = _ref.useDragAddIcon,
useDragAddIcon = _ref$useDragAddIcon === undefined ? false : _ref$useDragAddIcon,
_ref$noSelector = _ref.noSelector,
noSelector = _ref$noSelector === undefined ? false : _ref$noSelector;
_classCallCheck(this, Graphics);
/**
* Fabric image instance
* @type {fabric.Image}
*/
this.canvasImage = null;
/**
* Max width of canvas elements
* @type {number}
*/
this.cssMaxWidth = cssMaxWidth || DEFAULT_CSS_MAX_WIDTH;
/**
* Max height of canvas elements
* @type {number}
*/
this.cssMaxHeight = cssMaxHeight || DEFAULT_CSS_MAX_HEIGHT;
/**
* Use Itext mode for text component
* @type {boolean}
*/
this.useItext = useItext;
/**
* Use add drag icon mode for icon component
* @type {boolean}
*/
this.useDragAddIcon = useDragAddIcon;
/**
* option for group selector
* @type {boolean}
*/
this.noSelector = noSelector;
/**
* cropper Selection Style
* @type {Object}
*/
this.cropSelectionStyle = {};
/**
* Image name
* @type {string}
*/
this.imageName = '';
/**
* Object Map
* @type {Object}
* @private
*/
this._objects = {};
/**
* Fabric-Canvas instance
* @type {fabric.Canvas}
* @private
*/
this._canvas = null;
/**
* Drawing mode
* @type {string}
* @private
*/
this._drawingMode = drawingModes.NORMAL;
/**
* DrawingMode map
* @type {Object.<string, DrawingMode>}
* @private
*/
this._drawingModeMap = {};
/**
* Component map
* @type {Object.<string, Component>}
* @private
*/
this._componentMap = {};
/**
* fabric event handlers
* @type {Object.<string, function>}
* @private
*/
this._handler = {
onMouseDown: this._onMouseDown.bind(this),
onObjectAdded: this._onObjectAdded.bind(this),
onObjectRemoved: this._onObjectRemoved.bind(this),
onObjectMoved: this._onObjectMoved.bind(this),
onObjectScaled: this._onObjectScaled.bind(this),
onObjectSelected: this._onObjectSelected.bind(this),
onObjectRemove: this._onObjectRemove.bind(this),
onObjectRotateFix: this._onObjectRotateFix.bind(this),
onPathCreated: this._onPathCreated.bind(this),
onSelectionCleared: this._onSelectionCleared.bind(this)
};
this._setCanvasElement(element);
this._createDrawingModeInstances();
this._createComponents();
this._attachCanvasEvents();
}
/**
* Destroy canvas element
*/
_createClass(Graphics, [{
key: 'destroy',
value: function destroy() {
var wrapperEl = this._canvas.wrapperEl;
this._canvas.clear();
wrapperEl.parentNode.removeChild(wrapperEl);
}
/**
* Deactivates all objects on canvas
* @returns {Graphics} this
*/
}, {
key: 'deactivateAll',
value: function deactivateAll() {
this._canvas.deactivateAll();
return this;
}
/**
* Renders all objects on canvas
* @returns {Graphics} this
*/
}, {
key: 'renderAll',
value: function renderAll() {
this._canvas.renderAll();
return this;
}
/**
* Adds objects on canvas
* @param {Object|Array} objects - objects
*/
}, {
key: 'add',
value: function add(objects) {
var _canvas;
var theArgs = [];
if (isArray(objects)) {
theArgs = objects;
} else {
theArgs.push(objects);
}
(_canvas = this._canvas).add.apply(_canvas, theArgs);
}
/**
* Removes the object or group
* @param {Object} target - graphics object or group
* @returns {boolean} true if contains or false
*/
}, {
key: 'contains',
value: function contains(target) {
return this._canvas.contains(target);
}
/**
* Gets all objects or group
* @returns {Array} all objects, shallow copy
*/
}, {
key: 'getObjects',
value: function getObjects() {
return this._canvas.getObjects().slice();
}
/**
* Get an object by id
* @param {number} id - object id
* @returns {fabric.Object} object corresponding id
*/
}, {
key: 'getObject',
value: function getObject(id) {
return this._objects[id];
}
/**
* Removes the object or group
* @param {Object} target - graphics object or group
*/
}, {
key: 'remove',
value: function remove(target) {
this._canvas.remove(target);
}
/**
* Removes all object or group
* @param {boolean} includesBackground - remove the background image or not
* @returns {Array} all objects array which is removed
*/
}, {
key: 'removeAll',
value: function removeAll(includesBackground) {
var canvas = this._canvas;
var objects = canvas.getObjects().slice();
canvas.remove.apply(canvas, this._canvas.getObjects());
if (includesBackground) {
canvas.clear();
}
return objects;
}
/**
* Removes an object or group by id
* @param {number} id - object id
* @returns {Array} removed objects
*/
}, {
key: 'removeObjectById',
value: function removeObjectById(id) {
var objects = [];
var canvas = this._canvas;
var target = this.getObject(id);
var isValidGroup = target && target.isType('group') && !target.isEmpty();
if (isValidGroup) {
canvas.discardActiveGroup(); // restore states for each objects
target.forEachObject(function (obj) {
objects.push(obj);
obj.remove();
});
} else if (canvas.contains(target)) {
objects.push(target);
target.remove();
}
return objects;
}
/**
* Get an id by object instance
* @param {fabric.Object} object object
* @returns {number} object id if it exists or null
*/
}, {
key: 'getObjectId',
value: function getObjectId(object) {
var key = null;
for (key in this._objects) {
if (this._objects.hasOwnProperty(key)) {
if (object === this._objects[key]) {
return key;
}
}
}
return null;
}
/**
* Gets an active object or group
* @returns {Object} active object or group instance
*/
}, {
key: 'getActiveObject',
value: function getActiveObject() {
return this._canvas.getActiveObject();
}
/**
* Gets an active group object
* @returns {Object} active group object instance
*/
}, {
key: 'getActiveGroupObject',
value: function getActiveGroupObject() {
return this._canvas.getActiveGroup();
}
/**
* Activates an object or group
* @param {Object} target - target object or group
*/
}, {
key: 'setActiveObject',
value: function setActiveObject(target) {
this._canvas.setActiveObject(target);
}
/**
* Set Crop selection style
* @param {Object} style - Selection styles
*/
}, {
key: 'setCropSelectionStyle',
value: function setCropSelectionStyle(style) {
this.cropSelectionStyle = style;
}
/**
* Get component
* @param {string} name - Component name
* @returns {Component}
*/
}, {
key: 'getComponent',
value: function getComponent(name) {
return this._componentMap[name];
}
/**
* Get current drawing mode
* @returns {string}
*/
}, {
key: 'getDrawingMode',
value: function getDrawingMode() {
return this._drawingMode;
}
/**
* Start a drawing mode. If the current mode is not 'NORMAL', 'stopDrawingMode()' will be called first.
* @param {String} mode Can be one of <I>'CROPPER', 'FREE_DRAWING', 'LINE', 'TEXT', 'SHAPE'</I>
* @param {Object} [option] parameters of drawing mode, it's available with 'FREE_DRAWING', 'LINE_DRAWING'
* @param {Number} [option.width] brush width
* @param {String} [option.color] brush color
* @returns {boolean} true if success or false
*/
}, {
key: 'startDrawingMode',
value: function startDrawingMode(mode, option) {
if (this._isSameDrawingMode(mode)) {
return true;
}
// If the current mode is not 'NORMAL', 'stopDrawingMode()' will be called first.
this.stopDrawingMode();
var drawingModeInstance = this._getDrawingModeInstance(mode);
if (drawingModeInstance && drawingModeInstance.start) {
drawingModeInstance.start(this, option);
this._drawingMode = mode;
}
return !!drawingModeInstance;
}
/**
* Stop the current drawing mode and back to the 'NORMAL' mode
*/
}, {
key: 'stopDrawingMode',
value: function stopDrawingMode() {
if (this._isSameDrawingMode(drawingModes.NORMAL)) {
return;
}
var drawingModeInstance = this._getDrawingModeInstance(this.getDrawingMode());
if (drawingModeInstance && drawingModeInstance.end) {
drawingModeInstance.end(this);
}
this._drawingMode = drawingModes.NORMAL;
}
/**
* To data url from canvas
* @param {Object} options - options for toDataURL
* @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png"
* @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.
* @param {Number} [options.multiplier=1] Multiplier to scale by
* @param {Number} [options.left] Cropping left offset. Introduced in fabric v1.2.14
* @param {Number} [options.top] Cropping top offset. Introduced in fabric v1.2.14
* @param {Number} [options.width] Cropping width. Introduced in fabric v1.2.14
* @param {Number} [options.height] Cropping height. Introduced in fabric v1.2.14
* @returns {string} A DOMString containing the requested data URI.
*/
}, {
key: 'toDataURL',
value: function toDataURL(options) {
return this._canvas && this._canvas.toDataURL(options);
}
/**
* Save image(background) of canvas
* @param {string} name - Name of image
* @param {?fabric.Image} canvasImage - Fabric image instance
*/
}, {
key: 'setCanvasImage',
value: function setCanvasImage(name, canvasImage) {
if (canvasImage) {
stamp(canvasImage);
}
this.imageName = name;
this.canvasImage = canvasImage;
}
/**
* Set css max dimension
* @param {{width: number, height: number}} maxDimension - Max width & Max height
*/
}, {
key: 'setCssMaxDimension',
value: function setCssMaxDimension(maxDimension) {
this.cssMaxWidth = maxDimension.width || this.cssMaxWidth;
this.cssMaxHeight = maxDimension.height || this.cssMaxHeight;
}
/**
* Adjust canvas dimension with scaling image
*/
}, {
key: 'adjustCanvasDimension',
value: function adjustCanvasDimension() {
var canvasImage = this.canvasImage.scale(1);
var _canvasImage$getBound = canvasImage.getBoundingRect(),
width = _canvasImage$getBound.width,
height = _canvasImage$getBound.height;
var maxDimension = this._calcMaxDimension(width, height);
this.setCanvasCssDimension({
width: '100%',
height: '100%', // Set height '' for IE9
'max-width': maxDimension.width + 'px',
'max-height': maxDimension.height + 'px'
});
this.setCanvasBackstoreDimension({
width: width,
height: height
});
this._canvas.centerObject(canvasImage);
}
/**
* Set canvas dimension - css only
* {@link http://fabricjs.com/docs/fabric.Canvas.html#setDimensions}
* @param {Object} dimension - Canvas css dimension
*/
}, {
key: 'setCanvasCssDimension',
value: function setCanvasCssDimension(dimension) {
this._canvas.setDimensions(dimension, cssOnly);
}
/**
* Set canvas dimension - backstore only
* {@link http://fabricjs.com/docs/fabric.Canvas.html#setDimensions}
* @param {Object} dimension - Canvas backstore dimension
*/
}, {
key: 'setCanvasBackstoreDimension',
value: function setCanvasBackstoreDimension(dimension) {
this._canvas.setDimensions(dimension, backstoreOnly);
}
/**
* Set image properties
* {@link http://fabricjs.com/docs/fabric.Image.html#set}
* @param {Object} setting - Image properties
* @param {boolean} [withRendering] - If true, The changed image will be reflected in the canvas
*/
}, {
key: 'setImageProperties',
value: function setImageProperties(setting, withRendering) {
var canvasImage = this.canvasImage;
if (!canvasImage) {
return;
}
canvasImage.set(setting).setCoords();
if (withRendering) {
this._canvas.renderAll();
}
}
/**
* Returns canvas element of fabric.Canvas[[lower-canvas]]
* @returns {HTMLCanvasElement}
*/
}, {
key: 'getCanvasElement',
value: function getCanvasElement() {
return this._canvas.getElement();
}
/**
* Get fabric.Canvas instance
* @returns {fabric.Canvas}
* @private
*/
}, {
key: 'getCanvas',
value: function getCanvas() {
return this._canvas;
}
/**
* Get canvasImage (fabric.Image instance)
* @returns {fabric.Image}
*/
}, {
key: 'getCanvasImage',
value: function getCanvasImage() {
return this.canvasImage;
}
/**
* Get image name
* @returns {string}
*/
}, {
key: 'getImageName',
value: function getImageName() {
return this.imageName;
}
/**
* Add image object on canvas
* @param {string} imgUrl - Image url to make object
* @returns {Promise}
*/
}, {
key: 'addImageObject',
value: function addImageObject(imgUrl) {
var _this = this;
var callback = this._callbackAfterLoadingImageObject.bind(this);
return new _promise2.default(function (resolve) {
_fabric2.default.Image.fromURL(imgUrl, function (image) {
callback(image);
resolve(_this.createObjectProperties(image));
}, {
crossOrigin: 'Anonymous'
});
});
}
/**
* Get center position of canvas
* @returns {Object} {left, top}
*/
}, {
key: 'getCenter',
value: function getCenter() {
return this._canvas.getCenter();
}
/**
* Get cropped rect
* @returns {Object} rect
*/
}, {
key: 'getCropzoneRect',
value: function getCropzoneRect() {
return this.getComponent(components.CROPPER).getCropzoneRect();
}
/**
* Get cropped image data
* @param {Object} cropRect cropzone rect
* @param {Number} cropRect.left left position
* @param {Number} cropRect.top top position
* @param {Number} cropRect.width width
* @param {Number} cropRect.height height
* @returns {?{imageName: string, url: string}} cropped Image data
*/
}, {
key: 'getCroppedImageData',
value: function getCroppedImageData(cropRect) {
return this.getComponent(components.CROPPER).getCroppedImageData(cropRect);
}
/**
* Set brush option
* @param {Object} option brush option
* @param {Number} option.width width
* @param {String} option.color color like 'FFFFFF', 'rgba(0, 0, 0, 0.5)'
*/
}, {
key: 'setBrush',
value: function setBrush(option) {
var drawingMode = this._drawingMode;
var compName = components.FREE_DRAWING;
if (drawingMode === drawingModes.LINE) {
compName = drawingModes.LINE;
}
this.getComponent(compName).setBrush(option);
}
/**
* Set states of current drawing shape
* @param {string} type - Shape type (ex: 'rect', 'circle', 'triangle')
* @param {Object} [options] - Shape options
* @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
* @param {string} [options.stoke] - Shape outline color
* @param {number} [options.strokeWidth] - Shape outline width
* @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
* @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
* @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
* @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
* @param {number} [options.isRegular] - Whether resizing shape has 1:1 ratio or not
*/
}, {
key: 'setDrawingShape',
value: function setDrawingShape(type, options) {
this.getComponent(components.SHAPE).setStates(type, options);
}
/**
* Register icon paths
* @param {Object} pathInfos - Path infos
* @param {string} pathInfos.key - key
* @param {string} pathInfos.value - value
*/
}, {
key: 'registerPaths',
value: function registerPaths(pathInfos) {
this.getComponent(components.ICON).registerPaths(pathInfos);
}
/**
* Change cursor style
* @param {string} cursorType - cursor type
*/
}, {
key: 'changeCursor',
value: function changeCursor(cursorType) {
var canvas = this.getCanvas();
canvas.defaultCursor = cursorType;
canvas.renderAll();
}
/**
* Whether it has the filter or not
* @param {string} type - Filter type
* @returns {boolean} true if it has the filter
*/
}, {
key: 'hasFilter',
value: function hasFilter(type) {
return this.getComponent(components.FILTER).hasFilter(type);
}
/**
* Set selection style of fabric object by init option
* @param {Object} styles - Selection styles
*/
}, {
key: 'setSelectionStyle',
value: function setSelectionStyle(styles) {
extend(fObjectOptions.SELECTION_STYLE, styles);
}
/**
* Set object properties
* @param {number} id - object id
* @param {Object} props - props
* @param {string} [props.fill] Color
* @param {string} [props.fontFamily] Font type for text
* @param {number} [props.fontSize] Size
* @param {string} [props.fontStyle] Type of inclination (normal / italic)
* @param {string} [props.fontWeight] Type of thicker or thinner looking (normal / bold)
* @param {string} [props.textAlign] Type of text align (left / center / right)
* @param {string} [props.textDecoraiton] Type of line (underline / line-throgh / overline)
* @returns {Object} applied properties
*/
}, {
key: 'setObjectProperties',
value: function setObjectProperties(id, props) {
var object = this.getObject(id);
var clone = extend({}, props);
object.set(clone);
object.setCoords();
this.getCanvas().renderAll();
return clone;
}
/**
* Get object properties corresponding key
* @param {number} id - object id
* @param {Array<string>|ObjectProps|string} keys - property's key
* @returns {Object} properties
*/
}, {
key: 'getObjectProperties',
value: function getObjectProperties(id, keys) {
var object = this.getObject(id);
var props = {};
if (isString(keys)) {
props[keys] = object[keys];
} else if (isArray(keys)) {
forEachArray(keys, function (value) {
props[value] = object[value];
});
} else {
forEachOwnProperties(keys, function (value, key) {
props[key] = object[key];
});
}
return props;
}
/**
* Get object position by originX, originY
* @param {number} id - object id
* @param {string} originX - can be 'left', 'center', 'right'
* @param {string} originY - can be 'top', 'center', 'bottom'
* @returns {Object} {{x:number, y: number}} position by origin if id is valid, or null
*/
}, {
key: 'getObjectPosition',
value: function getObjectPosition(id, originX, originY) {
var targetObj = this.getObject(id);
if (!targetObj) {
return null;
}
return targetObj.getPointByOrigin(originX, originY);
}
/**
* Set object position by originX, originY
* @param {number} id - object id
* @param {Object} posInfo - position object
* @param {number} posInfo.x - x position
* @param {number} posInfo.y - y position
* @param {string} posInfo.originX - can be 'left', 'center', 'right'
* @param {string} posInfo.originY - can be 'top', 'center', 'bottom'
* @returns {boolean} true if target id is valid or false
*/
}, {
key: 'setObjectPosition',
value: function setObjectPosition(id, posInfo) {
var targetObj = this.getObject(id);
var x = posInfo.x,
y = posInfo.y,
originX = posInfo.originX,
originY = posInfo.originY;
if (!targetObj) {
return false;
}
var targetOrigin = targetObj.getPointByOrigin(originX, originY);
var centerOrigin = targetObj.getPointByOrigin('center', 'center');
var diffX = centerOrigin.x - targetOrigin.x;
var diffY = centerOrigin.y - targetOrigin.y;
targetObj.set({
left: x + diffX,
top: y + diffY
});
targetObj.setCoords();
return true;
}
/**
* Get the canvas size
* @returns {Object} {{width: number, height: number}} image size
*/
}, {
key: 'getCanvasSize',
value: function getCanvasSize() {
var image = this.getCanvasImage();
return {
width: image ? image.width : 0,
height: image ? image.height : 0
};
}
/**
* Get a DrawingMode instance
* @param {string} modeName - DrawingMode Class Name
* @returns {DrawingMode} DrawingMode instance
* @private
*/
}, {
key: '_getDrawingModeInstance',
value: function _getDrawingModeInstance(modeName) {
return this._drawingModeMap[modeName];
}
/**
* Set canvas element to fabric.Canvas
* @param {jQuery|Element|string} element - Wrapper or canvas element or selector
* @private
*/
}, {
key: '_setCanvasElement',
value: function _setCanvasElement(element) {
var selectedElement = void 0;
var canvasElement = void 0;
if (element.jquery) {
selectedElement = element[0];
} else if (element.nodeType) {
selectedElement = element;
} else {
selectedElement = document.querySelector(element);
}
if (selectedElement.nodeName.toUpperCase() !== 'CANVAS') {
canvasElement = document.createElement('canvas');
selectedElement.appendChild(canvasElement);
}
this._canvas = new _fabric2.default.Canvas(canvasElement, {
containerClass: 'tui-image-editor-canvas-container',
enableRetinaScaling: false,
noSelector: this.noSelector
});
}
/**
* Creates DrawingMode instances
* @private
*/
}, {
key: '_createDrawingModeInstances',
value: function _createDrawingModeInstances() {
this._register(this._drawingModeMap, new _cropper4.default());
this._register(this._drawingModeMap, new _freeDrawing4.default());
this._register(this._drawingModeMap, new _lineDrawing2.default());
this._register(this._drawingModeMap, new _shape4.default());
this._register(this._drawingModeMap, new _text4.default());
}
/**
* Create components
* @private
*/
}, {
key: '_createComponents',
value: function _createComponents() {
this._register(this._componentMap, new _imageLoader2.default(this));
this._register(this._componentMap, new _cropper2.default(this));
this._register(this._componentMap, new _flip2.default(this));
this._register(this._componentMap, new _rotation2.default(this));
this._register(this._componentMap, new _freeDrawing2.default(this));
this._register(this._componentMap, new _line2.default(this));
this._register(this._componentMap, new _text2.default(this));
this._register(this._componentMap, new _icon2.default(this));
this._register(this._componentMap, new _filter2.default(this));
this._register(this._componentMap, new _shape2.default(this));
}
/**
* Register component
* @param {Object} map - map object
* @param {Object} module - module which has getName method
* @private
*/
}, {
key: '_register',
value: function _register(map, module) {
map[module.getName()] = module;
}
/**
* Get the current drawing mode is same with given mode
* @param {string} mode drawing mode
* @returns {boolean} true if same or false
*/
}, {
key: '_isSameDrawingMode',
value: function _isSameDrawingMode(mode) {
return this.getDrawingMode() === mode;
}
/**
* Calculate max dimension of canvas
* The css-max dimension is dynamically decided with maintaining image ratio
* The css-max dimension is lower than canvas dimension (attribute of canvas, not css)
* @param {number} width - Canvas width
* @param {number} height - Canvas height
* @returns {{width: number, height: number}} - Max width & Max height
* @private
*/
}, {
key: '_calcMaxDimension',
value: function _calcMaxDimension(width, height) {
var wScaleFactor = this.cssMaxWidth / width;
var hScaleFactor = this.cssMaxHeight / height;
var cssMaxWidth = Math.min(width, this.cssMaxWidth);
var cssMaxHeight = Math.min(height, this.cssMaxHeight);
if (wScaleFactor < 1 && wScaleFactor < hScaleFactor) {
cssMaxWidth = width * wScaleFactor;
cssMaxHeight = height * wScaleFactor;
} else if (hScaleFactor < 1 && hScaleFactor < wScaleFactor) {
cssMaxWidth = width * hScaleFactor;
cssMaxHeight = height * hScaleFactor;
}
return {
width: Math.floor(cssMaxWidth),
height: Math.floor(cssMaxHeight)
};
}
/**
* Callback function after loading image
* @param {fabric.Image} obj - Fabric image object
* @private
*/
}, {
key: '_callbackAfterLoadingImageObject',
value: function _callbackAfterLoadingImageObject(obj) {
var centerPos = this.getCanvasImage().getCenterPoint();
obj.set(_consts2.default.fObjectOptions.SELECTION_STYLE);
obj.set({
left: centerPos.x,
top: centerPos.y,
crossOrigin: 'Anonymous'
});
this.getCanvas().add(obj).setActiveObject(obj);
}
/**
* Attach canvas's events
*/
}, {
key: '_attachCanvasEvents',
value: function _attachCanvasEvents() {
var canvas = this._canvas;
var handler = this._handler;
canvas.on({
'mouse:down': handler.onMouseDown,
'object:added': handler.onObjectAdded,
'object:removed': handler.onObjectRemoved,
'object:moving': handler.onObjectMoved,
'object:scaling': handler.onObjectScaled,
'object:selected': handler.onObjectSelected,
'object:remove': handler.onObjectRemove,
'object:rotateFix': handler.onObjectRotateFix,
'path:created': handler.onPathCreated,
'selection:cleared': handler.onSelectionCleared
});
}
/**
* "mouse:down" canvas event handler
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event
* @private
*/
}, {
key: '_onMouseDown',
value: function _onMouseDown(fEvent) {
var originPointer = this._canvas.getPointer(fEvent.e);
this.fire(events.MOUSE_DOWN, fEvent.e, originPointer);
}
/**
* "object:added" canvas event handler
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event
* @private
*/
}, {
key: '_onObjectAdded',
value: function _onObjectAdded(fEvent) {
var obj = fEvent.target;
if (obj.isType('cropzone')) {
return;
}
this._addFabricObject(obj);
}
/**
* "object:removed" canvas event handler
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event
* @private
*/
}, {
key: '_onObjectRemoved',
value: function _onObjectRemoved(fEvent) {
var obj = fEvent.target;
this._removeFabricObject(stamp(obj));
}
/**
* "object:removed" canvas event handler
* @param {Object} target - Fabric event
* @private
*/
}, {
key: '_onObjectRemove',
value: function _onObjectRemove(target) {
this.fire(events.OBJECT_REMOVE, target);
}
}, {
key: '_onObjectRotateFix',
value: function _onObjectRotateFix(data) {
this.fire(events.OBJECT_ROTATE_FIX, data);
}
/**
* "object:moving" canvas event handler
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event
* @private
*/
}, {
key: '_onObjectMoved',
value: function _onObjectMoved(fEvent) {
var target = fEvent.target;
var params = this.createObjectProperties(target);
this.fire(events.OBJECT_MOVED, params);
}
/**
* "object:scaling" canvas event handler
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event
* @private
*/
}, {
key: '_onObjectScaled',
value: function _onObjectScaled(fEvent) {
var target = fEvent.target;
var params = this.createObjectProperties(target);
this.fire(events.OBJECT_SCALED, params);
}
/**
* "object:selected" canvas event handler
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event
* @private
*/
}, {
key: '_onObjectSelected',
value: function _onObjectSelected(fEvent) {
var target = fEvent.target;
var params = this.createObjectProperties(target);
this.fire(events.OBJECT_ACTIVATED, params);
}
/**
* "path:created" canvas event handler
* @param {{path: fabric.Path}} obj - Path object
* @private
*/
}, {
key: '_onPathCreated',
value: function _onPathCreated(obj) {
obj.path.set(_consts2.default.fObjectOptions.SELECTION_STYLE);
var params = this.createObjectProperties(obj.path);
this.fire(events.ADD_OBJECT, params);
}
/**
* "selction:cleared" canvas event handler
* @private
*/
}, {
key: '_onSelectionCleared',
value: function _onSelectionCleared() {
this.fire(events.SELECTION_CLEARED);
}
/**
* "selction:created" canvas event handler
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event
* @private
*/
}, {
key: '_onSelectionCreated',
value: function _onSelectionCreated(fEvent) {
this.fire(events.SELECTION_CREATED, fEvent.target);
}
/**
* Canvas discard selection all
*/
}, {
key: 'discardSelection',
value: function discardSelection() {
this._canvas.discardActiveGroup();
this._canvas.discardActiveObject();
this._canvas.renderAll();
}
/**
* Canvas Selectable status change
* @param {boolean} selectable - expect status
*/
}, {
key: 'changeSelectableAll',
value: function changeSelectableAll(selectable) {
this._canvas.forEachObject(function (obj) {
obj.selectable = selectable;
obj.hoverCursor = selectable ? 'move' : 'crosshair';
});
}
/**
* Return object's properties
* @param {fabric.Object} obj - fabric object
* @returns {Object} properties object
*/
}, {
key: 'createObjectProperties',
value: function createObjectProperties(obj) {
var predefinedKeys = ['left', 'top', 'width', 'height', 'fill', 'stroke', 'strokeWidth', 'opacity'];
var props = {
id: stamp(obj),
type: obj.type
};
extend(props, _util2.default.getProperties(obj, predefinedKeys));
if (['i-text', 'text'].indexOf(obj.type) > -1) {
extend(props, this._createTextProperties(obj, props));
}
return props;
}
/**
* Get text object's properties
* @param {fabric.Object} obj - fabric text object
* @param {Object} props - properties
* @returns {Object} properties object
*/
}, {
key: '_createTextProperties',
value: function _createTextProperties(obj) {
var predefinedKeys = ['text', 'fontFamily', 'fontSize', 'fontStyle', 'textAlign', 'textDecoration'];
var props = {};
extend(props, _util2.default.getProperties(obj, predefinedKeys));
return props;
}
/**
* Add object array by id
* @param {fabric.Object} obj - fabric object
* @returns {number} object id
*/
}, {
key: '_addFabricObject',
value: function _addFabricObject(obj) {
var id = stamp(obj);
this._objects[id] = obj;
return id;
}
/**
* Remove an object in array yb id
* @param {number} id - object id
*/
}, {
key: '_removeFabricObject',
value: function _removeFabricObject(id) {
delete this._objects[id];
}
}]);
return Graphics;
}();
CustomEvents.mixin(Graphics);
module.exports = Graphics;
/***/ }),
/* 105 */
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(Buffer, global, process) {var fabric = fabric || {
version: "1.6.7"
};
if (true) {
exports.fabric = fabric;
}
if (typeof document !== "undefined" && typeof window !== "undefined") {
fabric.document = document;
fabric.window = window;
window.fabric = fabric;
} else {
fabric.document = __webpack_require__(111).jsdom("<!DOCTYPE html><html><head></head><body></body></html>");
if (fabric.document.createWindow) {
fabric.window = fabric.document.createWindow();
} else {
fabric.window = fabric.document.parentWindow;
}
}
fabric.isTouchSupported = "ontouchstart" in fabric.document.documentElement;
fabric.isLikelyNode = typeof Buffer !== "undefined" && typeof window === "undefined";
fabric.SHARED_ATTRIBUTES = [ "display", "transform", "fill", "fill-opacity", "fill-rule", "opacity", "stroke", "stroke-dasharray", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "id" ];
fabric.DPI = 96;
fabric.reNum = "(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)";
fabric.fontPaths = {};
fabric.charWidthsCache = {};
fabric.devicePixelRatio = fabric.window.devicePixelRatio || fabric.window.webkitDevicePixelRatio || fabric.window.mozDevicePixelRatio || 1;
(function() {
function _removeEventListener(eventName, handler) {
if (!this.__eventListeners[eventName]) {
return;
}
var eventListener = this.__eventListeners[eventName];
if (handler) {
eventListener[eventListener.indexOf(handler)] = false;
} else {
fabric.util.array.fill(eventListener, false);
}
}
function observe(eventName, handler) {
if (!this.__eventListeners) {
this.__eventListeners = {};
}
if (arguments.length === 1) {
for (var prop in eventName) {
this.on(prop, eventName[prop]);
}
} else {
if (!this.__eventListeners[eventName]) {
this.__eventListeners[eventName] = [];
}
this.__eventListeners[eventName].push(handler);
}
return this;
}
function stopObserving(eventName, handler) {
if (!this.__eventListeners) {
return;
}
if (arguments.length === 0) {
for (eventName in this.__eventListeners) {
_removeEventListener.call(this, eventName);
}
} else if (arguments.length === 1 && typeof arguments[0] === "object") {
for (var prop in eventName) {
_removeEventListener.call(this, prop, eventName[prop]);
}
} else {
_removeEventListener.call(this, eventName, handler);
}
return this;
}
function fire(eventName, options) {
if (!this.__eventListeners) {
return;
}
var listenersForEvent = this.__eventListeners[eventName];
if (!listenersForEvent) {
return;
}
for (var i = 0, len = listenersForEvent.length; i < len; i++) {
listenersForEvent[i] && listenersForEvent[i].call(this, options || {});
}
this.__eventListeners[eventName] = listenersForEvent.filter(function(value) {
return value !== false;
});
return this;
}
fabric.Observable = {
observe: observe,
stopObserving: stopObserving,
fire: fire,
on: observe,
off: stopObserving,
trigger: fire
};
})();
fabric.Collection = {
_objects: [],
add: function() {
this._objects.push.apply(this._objects, arguments);
if (this._onObjectAdded) {
for (var i = 0, length = arguments.length; i < length; i++) {
this._onObjectAdded(arguments[i]);
}
}
this.renderOnAddRemove && this.renderAll();
return this;
},
insertAt: function(object, index, nonSplicing) {
var objects = this.getObjects();
if (nonSplicing) {
objects[index] = object;
} else {
objects.splice(index, 0, object);
}
this._onObjectAdded && this._onObjectAdded(object);
this.renderOnAddRemove && this.renderAll();
return this;
},
remove: function() {
var objects = this.getObjects(), index, somethingRemoved = false;
for (var i = 0, length = arguments.length; i < length; i++) {
index = objects.indexOf(arguments[i]);
if (index !== -1) {
somethingRemoved = true;
objects.splice(index, 1);
this._onObjectRemoved && this._onObjectRemoved(arguments[i]);
}
}
this.renderOnAddRemove && somethingRemoved && this.renderAll();
return this;
},
forEachObject: function(callback, context) {
var objects = this.getObjects();
for (var i = 0, len = objects.length; i < len; i++) {
callback.call(context, objects[i], i, objects);
}
return this;
},
getObjects: function(type) {
if (typeof type === "undefined") {
return this._objects;
}
return this._objects.filter(function(o) {
return o.type === type;
});
},
item: function(index) {
return this.getObjects()[index];
},
isEmpty: function() {
return this.getObjects().length === 0;
},
size: function() {
return this.getObjects().length;
},
contains: function(object) {
return this.getObjects().indexOf(object) > -1;
},
complexity: function() {
return this.getObjects().reduce(function(memo, current) {
memo += current.complexity ? current.complexity() : 0;
return memo;
}, 0);
}
};
(function(global) {
var sqrt = Math.sqrt, atan2 = Math.atan2, pow = Math.pow, abs = Math.abs, PiBy180 = Math.PI / 180;
fabric.util = {
removeFromArray: function(array, value) {
var idx = array.indexOf(value);
if (idx !== -1) {
array.splice(idx, 1);
}
return array;
},
getRandomInt: function(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
},
degreesToRadians: function(degrees) {
return degrees * PiBy180;
},
radiansToDegrees: function(radians) {
return radians / PiBy180;
},
rotatePoint: function(point, origin, radians) {
point.subtractEquals(origin);
var v = fabric.util.rotateVector(point, radians);
return new fabric.Point(v.x, v.y).addEquals(origin);
},
rotateVector: function(vector, radians) {
var sin = Math.sin(radians), cos = Math.cos(radians), rx = vector.x * cos - vector.y * sin, ry = vector.x * sin + vector.y * cos;
return {
x: rx,
y: ry
};
},
transformPoint: function(p, t, ignoreOffset) {
if (ignoreOffset) {
return new fabric.Point(t[0] * p.x + t[2] * p.y, t[1] * p.x + t[3] * p.y);
}
return new fabric.Point(t[0] * p.x + t[2] * p.y + t[4], t[1] * p.x + t[3] * p.y + t[5]);
},
makeBoundingBoxFromPoints: function(points) {
var xPoints = [ points[0].x, points[1].x, points[2].x, points[3].x ], minX = fabric.util.array.min(xPoints), maxX = fabric.util.array.max(xPoints), width = Math.abs(minX - maxX), yPoints = [ points[0].y, points[1].y, points[2].y, points[3].y ], minY = fabric.util.array.min(yPoints), maxY = fabric.util.array.max(yPoints), height = Math.abs(minY - maxY);
return {
left: minX,
top: minY,
width: width,
height: height
};
},
invertTransform: function(t) {
var a = 1 / (t[0] * t[3] - t[1] * t[2]), r = [ a * t[3], -a * t[1], -a * t[2], a * t[0] ], o = fabric.util.transformPoint({
x: t[4],
y: t[5]
}, r, true);
r[4] = -o.x;
r[5] = -o.y;
return r;
},
toFixed: function(number, fractionDigits) {
return parseFloat(Number(number).toFixed(fractionDigits));
},
parseUnit: function(value, fontSize) {
var unit = /\D{0,2}$/.exec(value), number = parseFloat(value);
if (!fontSize) {
fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;
}
switch (unit[0]) {
case "mm":
return number * fabric.DPI / 25.4;
case "cm":
return number * fabric.DPI / 2.54;
case "in":
return number * fabric.DPI;
case "pt":
return number * fabric.DPI / 72;
case "pc":
return number * fabric.DPI / 72 * 12;
case "em":
return number * fontSize;
default:
return number;
}
},
falseFunction: function() {
return false;
},
getKlass: function(type, namespace) {
type = fabric.util.string.camelize(type.charAt(0).toUpperCase() + type.slice(1));
return fabric.util.resolveNamespace(namespace)[type];
},
resolveNamespace: function(namespace) {
if (!namespace) {
return fabric;
}
var parts = namespace.split("."), len = parts.length, i, obj = global || fabric.window;
for (i = 0; i < len; ++i) {
obj = obj[parts[i]];
}
return obj;
},
loadImage: function(url, callback, context, crossOrigin) {
if (!url) {
callback && callback.call(context, url);
return;
}
var img = fabric.util.createImage();
img.onload = function() {
callback && callback.call(context, img);
img = img.onload = img.onerror = null;
};
img.onerror = function() {
fabric.log("Error loading " + img.src);
callback && callback.call(context, null, true);
img = img.onload = img.onerror = null;
};
if (url.indexOf("data") !== 0 && crossOrigin) {
img.crossOrigin = crossOrigin;
}
img.src = url;
},
enlivenObjects: function(objects, callback, namespace, reviver) {
objects = objects || [];
function onLoaded() {
if (++numLoadedObjects === numTotalObjects) {
callback && callback(enlivenedObjects);
}
}
var enlivenedObjects = [], numLoadedObjects = 0, numTotalObjects = objects.length;
if (!numTotalObjects) {
callback && callback(enlivenedObjects);
return;
}
objects.forEach(function(o, index) {
if (!o || !o.type) {
onLoaded();
return;
}
var klass = fabric.util.getKlass(o.type, namespace);
if (klass.async) {
klass.fromObject(o, function(obj, error) {
if (!error) {
enlivenedObjects[index] = obj;
reviver && reviver(o, enlivenedObjects[index]);
}
onLoaded();
});
} else {
enlivenedObjects[index] = klass.fromObject(o);
reviver && reviver(o, enlivenedObjects[index]);
onLoaded();
}
});
},
groupSVGElements: function(elements, options, path) {
var object;
object = new fabric.PathGroup(elements, options);
if (typeof path !== "undefined") {
object.setSourcePath(path);
}
return object;
},
populateWithProperties: function(source, destination, properties) {
if (properties && Object.prototype.toString.call(properties) === "[object Array]") {
for (var i = 0, len = properties.length; i < len; i++) {
if (properties[i] in source) {
destination[properties[i]] = source[properties[i]];
}
}
}
},
drawDashedLine: function(ctx, x, y, x2, y2, da) {
var dx = x2 - x, dy = y2 - y, len = sqrt(dx * dx + dy * dy), rot = atan2(dy, dx), dc = da.length, di = 0, draw = true;
ctx.save();
ctx.translate(x, y);
ctx.moveTo(0, 0);
ctx.rotate(rot);
x = 0;
while (len > x) {
x += da[di++ % dc];
if (x > len) {
x = len;
}
ctx[draw ? "lineTo" : "moveTo"](x, 0);
draw = !draw;
}
ctx.restore();
},
createCanvasElement: function(canvasEl) {
canvasEl || (canvasEl = fabric.document.createElement("canvas"));
if (!canvasEl.getContext && typeof G_vmlCanvasManager !== "undefined") {
G_vmlCanvasManager.initElement(canvasEl);
}
return canvasEl;
},
createImage: function() {
return fabric.isLikelyNode ? new (__webpack_require__(112).Image)() : fabric.document.createElement("img");
},
createAccessors: function(klass) {
var proto = klass.prototype, i, propName, capitalizedPropName, setterName, getterName;
for (i = proto.stateProperties.length; i--; ) {
propName = proto.stateProperties[i];
capitalizedPropName = propName.charAt(0).toUpperCase() + propName.slice(1);
setterName = "set" + capitalizedPropName;
getterName = "get" + capitalizedPropName;
if (!proto[getterName]) {
proto[getterName] = function(property) {
return new Function('return this.get("' + property + '")');
}(propName);
}
if (!proto[setterName]) {
proto[setterName] = function(property) {
return new Function("value", 'return this.set("' + property + '", value)');
}(propName);
}
}
},
clipContext: function(receiver, ctx) {
ctx.save();
ctx.beginPath();
receiver.clipTo(ctx);
ctx.clip();
},
multiplyTransformMatrices: function(a, b, is2x2) {
return [ a[0] * b[0] + a[2] * b[1], a[1] * b[0] + a[3] * b[1], a[0] * b[2] + a[2] * b[3], a[1] * b[2] + a[3] * b[3], is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4], is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5] ];
},
qrDecompose: function(a) {
var angle = atan2(a[1], a[0]), denom = pow(a[0], 2) + pow(a[1], 2), scaleX = sqrt(denom), scaleY = (a[0] * a[3] - a[2] * a[1]) / scaleX, skewX = atan2(a[0] * a[2] + a[1] * a[3], denom);
return {
angle: angle / PiBy180,
scaleX: scaleX,
scaleY: scaleY,
skewX: skewX / PiBy180,
skewY: 0,
translateX: a[4],
translateY: a[5]
};
},
customTransformMatrix: function(scaleX, scaleY, skewX) {
var skewMatrixX = [ 1, 0, abs(Math.tan(skewX * PiBy180)), 1 ], scaleMatrix = [ abs(scaleX), 0, 0, abs(scaleY) ];
return fabric.util.multiplyTransformMatrices(scaleMatrix, skewMatrixX, true);
},
resetObjectTransform: function(target) {
target.scaleX = 1;
target.scaleY = 1;
target.skewX = 0;
target.skewY = 0;
target.flipX = false;
target.flipY = false;
target.setAngle(0);
},
getFunctionBody: function(fn) {
return (String(fn).match(/function[^{]*\{([\s\S]*)\}/) || {})[1];
},
isTransparent: function(ctx, x, y, tolerance) {
if (tolerance > 0) {
if (x > tolerance) {
x -= tolerance;
} else {
x = 0;
}
if (y > tolerance) {
y -= tolerance;
} else {
y = 0;
}
}
var _isTransparent = true, i, temp, imageData = ctx.getImageData(x, y, tolerance * 2 || 1, tolerance * 2 || 1), l = imageData.data.length;
for (i = 3; i < l; i += 4) {
temp = imageData.data[i];
_isTransparent = temp <= 0;
if (_isTransparent === false) {
break;
}
}
imageData = null;
return _isTransparent;
},
parsePreserveAspectRatioAttribute: function(attribute) {
var meetOrSlice = "meet", alignX = "Mid", alignY = "Mid", aspectRatioAttrs = attribute.split(" "), align;
if (aspectRatioAttrs && aspectRatioAttrs.length) {
meetOrSlice = aspectRatioAttrs.pop();
if (meetOrSlice !== "meet" && meetOrSlice !== "slice") {
align = meetOrSlice;
meetOrSlice = "meet";
} else if (aspectRatioAttrs.length) {
align = aspectRatioAttrs.pop();
}
}
alignX = align !== "none" ? align.slice(1, 4) : "none";
alignY = align !== "none" ? align.slice(5, 8) : "none";
return {
meetOrSlice: meetOrSlice,
alignX: alignX,
alignY: alignY
};
},
clearFabricFontCache: function(fontFamily) {
if (!fontFamily) {
fabric.charWidthsCache = {};
} else if (fabric.charWidthsCache[fontFamily]) {
delete fabric.charWidthsCache[fontFamily];
}
}
};
})( true ? exports : this);
(function() {
var arcToSegmentsCache = {}, segmentToBezierCache = {}, boundsOfCurveCache = {}, _join = Array.prototype.join;
function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) {
var argsString = _join.call(arguments);
if (arcToSegmentsCache[argsString]) {
return arcToSegmentsCache[argsString];
}
var PI = Math.PI, th = rotateX * PI / 180, sinTh = Math.sin(th), cosTh = Math.cos(th), fromX = 0, fromY = 0;
rx = Math.abs(rx);
ry = Math.abs(ry);
var px = -cosTh * toX * .5 - sinTh * toY * .5, py = -cosTh * toY * .5 + sinTh * toX * .5, rx2 = rx * rx, ry2 = ry * ry, py2 = py * py, px2 = px * px, pl = rx2 * ry2 - rx2 * py2 - ry2 * px2, root = 0;
if (pl < 0) {
var s = Math.sqrt(1 - pl / (rx2 * ry2));
rx *= s;
ry *= s;
} else {
root = (large === sweep ? -1 : 1) * Math.sqrt(pl / (rx2 * py2 + ry2 * px2));
}
var cx = root * rx * py / ry, cy = -root * ry * px / rx, cx1 = cosTh * cx - sinTh * cy + toX * .5, cy1 = sinTh * cx + cosTh * cy + toY * .5, mTheta = calcVectorAngle(1, 0, (px - cx) / rx, (py - cy) / ry), dtheta = calcVectorAngle((px - cx) / rx, (py - cy) / ry, (-px - cx) / rx, (-py - cy) / ry);
if (sweep === 0 && dtheta > 0) {
dtheta -= 2 * PI;
} else if (sweep === 1 && dtheta < 0) {
dtheta += 2 * PI;
}
var segments = Math.ceil(Math.abs(dtheta / PI * 2)), result = [], mDelta = dtheta / segments, mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2), th3 = mTheta + mDelta;
for (var i = 0; i < segments; i++) {
result[i] = segmentToBezier(mTheta, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY);
fromX = result[i][4];
fromY = result[i][5];
mTheta = th3;
th3 += mDelta;
}
arcToSegmentsCache[argsString] = result;
return result;
}
function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) {
var argsString2 = _join.call(arguments);
if (segmentToBezierCache[argsString2]) {
return segmentToBezierCache[argsString2];
}
var costh2 = Math.cos(th2), sinth2 = Math.sin(th2), costh3 = Math.cos(th3), sinth3 = Math.sin(th3), toX = cosTh * rx * costh3 - sinTh * ry * sinth3 + cx1, toY = sinTh * rx * costh3 + cosTh * ry * sinth3 + cy1, cp1X = fromX + mT * (-cosTh * rx * sinth2 - sinTh * ry * costh2), cp1Y = fromY + mT * (-sinTh * rx * sinth2 + cosTh * ry * costh2), cp2X = toX + mT * (cosTh * rx * sinth3 + sinTh * ry * costh3), cp2Y = toY + mT * (sinTh * rx * sinth3 - cosTh * ry * costh3);
segmentToBezierCache[argsString2] = [ cp1X, cp1Y, cp2X, cp2Y, toX, toY ];
return segmentToBezierCache[argsString2];
}
function calcVectorAngle(ux, uy, vx, vy) {
var ta = Math.atan2(uy, ux), tb = Math.atan2(vy, vx);
if (tb >= ta) {
return tb - ta;
} else {
return 2 * Math.PI - (ta - tb);
}
}
fabric.util.drawArc = function(ctx, fx, fy, coords) {
var rx = coords[0], ry = coords[1], rot = coords[2], large = coords[3], sweep = coords[4], tx = coords[5], ty = coords[6], segs = [ [], [], [], [] ], segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);
for (var i = 0, len = segsNorm.length; i < len; i++) {
segs[i][0] = segsNorm[i][0] + fx;
segs[i][1] = segsNorm[i][1] + fy;
segs[i][2] = segsNorm[i][2] + fx;
segs[i][3] = segsNorm[i][3] + fy;
segs[i][4] = segsNorm[i][4] + fx;
segs[i][5] = segsNorm[i][5] + fy;
ctx.bezierCurveTo.apply(ctx, segs[i]);
}
};
fabric.util.getBoundsOfArc = function(fx, fy, rx, ry, rot, large, sweep, tx, ty) {
var fromX = 0, fromY = 0, bound, bounds = [], segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);
for (var i = 0, len = segs.length; i < len; i++) {
bound = getBoundsOfCurve(fromX, fromY, segs[i][0], segs[i][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5]);
bounds.push({
x: bound[0].x + fx,
y: bound[0].y + fy
});
bounds.push({
x: bound[1].x + fx,
y: bound[1].y + fy
});
fromX = segs[i][4];
fromY = segs[i][5];
}
return bounds;
};
function getBoundsOfCurve(x0, y0, x1, y1, x2, y2, x3, y3) {
var argsString = _join.call(arguments);
if (boundsOfCurveCache[argsString]) {
return boundsOfCurveCache[argsString];
}
var sqrt = Math.sqrt, min = Math.min, max = Math.max, abs = Math.abs, tvalues = [], bounds = [ [], [] ], a, b, c, t, t1, t2, b2ac, sqrtb2ac;
b = 6 * x0 - 12 * x1 + 6 * x2;
a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;
c = 3 * x1 - 3 * x0;
for (var i = 0; i < 2; ++i) {
if (i > 0) {
b = 6 * y0 - 12 * y1 + 6 * y2;
a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;
c = 3 * y1 - 3 * y0;
}
if (abs(a) < 1e-12) {
if (abs(b) < 1e-12) {
continue;
}
t = -c / b;
if (0 < t && t < 1) {
tvalues.push(t);
}
continue;
}
b2ac = b * b - 4 * c * a;
if (b2ac < 0) {
continue;
}
sqrtb2ac = sqrt(b2ac);
t1 = (-b + sqrtb2ac) / (2 * a);
if (0 < t1 && t1 < 1) {
tvalues.push(t1);
}
t2 = (-b - sqrtb2ac) / (2 * a);
if (0 < t2 && t2 < 1) {
tvalues.push(t2);
}
}
var x, y, j = tvalues.length, jlen = j, mt;
while (j--) {
t = tvalues[j];
mt = 1 - t;
x = mt * mt * mt * x0 + 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t * x3;
bounds[0][j] = x;
y = mt * mt * mt * y0 + 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t * y3;
bounds[1][j] = y;
}
bounds[0][jlen] = x0;
bounds[1][jlen] = y0;
bounds[0][jlen + 1] = x3;
bounds[1][jlen + 1] = y3;
var result = [ {
x: min.apply(null, bounds[0]),
y: min.apply(null, bounds[1])
}, {
x: max.apply(null, bounds[0]),
y: max.apply(null, bounds[1])
} ];
boundsOfCurveCache[argsString] = result;
return result;
}
fabric.util.getBoundsOfCurve = getBoundsOfCurve;
})();
(function() {
var slice = Array.prototype.slice;
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(searchElement) {
if (this === void 0 || this === null) {
throw new TypeError();
}
var t = Object(this), len = t.length >>> 0;
if (len === 0) {
return -1;
}
var n = 0;
if (arguments.length > 0) {
n = Number(arguments[1]);
if (n !== n) {
n = 0;
} else if (n !== 0 && n !== Number.POSITIVE_INFINITY && n !== Number.NEGATIVE_INFINITY) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
for (;k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
};
}
if (!Array.prototype.forEach) {
Array.prototype.forEach = function(fn, context) {
for (var i = 0, len = this.length >>> 0; i < len; i++) {
if (i in this) {
fn.call(context, this[i], i, this);
}
}
};
}
if (!Array.prototype.map) {
Array.prototype.map = function(fn, context) {
var result = [];
for (var i = 0, len = this.length >>> 0; i < len; i++) {
if (i in this) {
result[i] = fn.call(context, this[i], i, this);
}
}
return result;
};
}
if (!Array.prototype.every) {
Array.prototype.every = function(fn, context) {
for (var i = 0, len = this.length >>> 0; i < len; i++) {
if (i in this && !fn.call(context, this[i], i, this)) {
return false;
}
}
return true;
};
}
if (!Array.prototype.some) {
Array.prototype.some = function(fn, context) {
for (var i = 0, len = this.length >>> 0; i < len; i++) {
if (i in this && fn.call(context, this[i], i, this)) {
return true;
}
}
return false;
};
}
if (!Array.prototype.filter) {
Array.prototype.filter = function(fn, context) {
var result = [], val;
for (var i = 0, len = this.length >>> 0; i < len; i++) {
if (i in this) {
val = this[i];
if (fn.call(context, val, i, this)) {
result.push(val);
}
}
}
return result;
};
}
if (!Array.prototype.reduce) {
Array.prototype.reduce = function(fn) {
var len = this.length >>> 0, i = 0, rv;
if (arguments.length > 1) {
rv = arguments[1];
} else {
do {
if (i in this) {
rv = this[i++];
break;
}
if (++i >= len) {
throw new TypeError();
}
} while (true);
}
for (;i < len; i++) {
if (i in this) {
rv = fn.call(null, rv, this[i], i, this);
}
}
return rv;
};
}
function invoke(array, method) {
var args = slice.call(arguments, 2), result = [];
for (var i = 0, len = array.length; i < len; i++) {
result[i] = args.length ? array[i][method].apply(array[i], args) : array[i][method].call(array[i]);
}
return result;
}
function max(array, byProperty) {
return find(array, byProperty, function(value1, value2) {
return value1 >= value2;
});
}
function min(array, byProperty) {
return find(array, byProperty, function(value1, value2) {
return value1 < value2;
});
}
function fill(array, value) {
var k = array.length;
while (k--) {
array[k] = value;
}
return array;
}
function find(array, byProperty, condition) {
if (!array || array.length === 0) {
return;
}
var i = array.length - 1, result = byProperty ? array[i][byProperty] : array[i];
if (byProperty) {
while (i--) {
if (condition(array[i][byProperty], result)) {
result = array[i][byProperty];
}
}
} else {
while (i--) {
if (condition(array[i], result)) {
result = array[i];
}
}
}
return result;
}
fabric.util.array = {
fill: fill,
invoke: invoke,
min: min,
max: max
};
})();
(function() {
function extend(destination, source, deep) {
if (deep) {
if (!fabric.isLikelyNode && source instanceof Element) {
destination = source;
} else if (source instanceof Array) {
destination = source.map(function(v) {
return clone(v, deep);
});
} else if (source instanceof Object) {
for (var property in source) {
destination[property] = clone(source[property], deep);
}
} else {
destination = source;
}
} else {
for (var property in source) {
destination[property] = source[property];
}
}
return destination;
}
function clone(object, deep) {
return extend({}, object, deep);
}
fabric.util.object = {
extend: extend,
clone: clone
};
})();
(function() {
if (!String.prototype.trim) {
String.prototype.trim = function() {
return this.replace(/^[\s\xA0]+/, "").replace(/[\s\xA0]+$/, "");
};
}
function camelize(string) {
return string.replace(/-+(.)?/g, function(match, character) {
return character ? character.toUpperCase() : "";
});
}
function capitalize(string, firstLetterOnly) {
return string.charAt(0).toUpperCase() + (firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase());
}
function escapeXml(string) {
return string.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
}
fabric.util.string = {
camelize: camelize,
capitalize: capitalize,
escapeXml: escapeXml
};
})();
(function() {
var slice = Array.prototype.slice, apply = Function.prototype.apply, Dummy = function() {};
if (!Function.prototype.bind) {
Function.prototype.bind = function(thisArg) {
var _this = this, args = slice.call(arguments, 1), bound;
if (args.length) {
bound = function() {
return apply.call(_this, this instanceof Dummy ? this : thisArg, args.concat(slice.call(arguments)));
};
} else {
bound = function() {
return apply.call(_this, this instanceof Dummy ? this : thisArg, arguments);
};
}
Dummy.prototype = this.prototype;
bound.prototype = new Dummy();
return bound;
};
}
})();
(function() {
var slice = Array.prototype.slice, emptyFunction = function() {}, IS_DONTENUM_BUGGY = function() {
for (var p in {
toString: 1
}) {
if (p === "toString") {
return false;
}
}
return true;
}(), addMethods = function(klass, source, parent) {
for (var property in source) {
if (property in klass.prototype && typeof klass.prototype[property] === "function" && (source[property] + "").indexOf("callSuper") > -1) {
klass.prototype[property] = function(property) {
return function() {
var superclass = this.constructor.superclass;
this.constructor.superclass = parent;
var returnValue = source[property].apply(this, arguments);
this.constructor.superclass = superclass;
if (property !== "initialize") {
return returnValue;
}
};
}(property);
} else {
klass.prototype[property] = source[property];
}
if (IS_DONTENUM_BUGGY) {
if (source.toString !== Object.prototype.toString) {
klass.prototype.toString = source.toString;
}
if (source.valueOf !== Object.prototype.valueOf) {
klass.prototype.valueOf = source.valueOf;
}
}
}
};
function Subclass() {}
function callSuper(methodName) {
var fn = this.constructor.superclass.prototype[methodName];
return arguments.length > 1 ? fn.apply(this, slice.call(arguments, 1)) : fn.call(this);
}
function createClass() {
var parent = null, properties = slice.call(arguments, 0);
if (typeof properties[0] === "function") {
parent = properties.shift();
}
function klass() {
this.initialize.apply(this, arguments);
}
klass.superclass = parent;
klass.subclasses = [];
if (parent) {
Subclass.prototype = parent.prototype;
klass.prototype = new Subclass();
parent.subclasses.push(klass);
}
for (var i = 0, length = properties.length; i < length; i++) {
addMethods(klass, properties[i], parent);
}
if (!klass.prototype.initialize) {
klass.prototype.initialize = emptyFunction;
}
klass.prototype.constructor = klass;
klass.prototype.callSuper = callSuper;
return klass;
}
fabric.util.createClass = createClass;
})();
(function() {
var unknown = "unknown";
function areHostMethods(object) {
var methodNames = Array.prototype.slice.call(arguments, 1), t, i, len = methodNames.length;
for (i = 0; i < len; i++) {
t = typeof object[methodNames[i]];
if (!/^(?:function|object|unknown)$/.test(t)) {
return false;
}
}
return true;
}
var getElement, setElement, getUniqueId = function() {
var uid = 0;
return function(element) {
return element.__uniqueID || (element.__uniqueID = "uniqueID__" + uid++);
};
}();
(function() {
var elements = {};
getElement = function(uid) {
return elements[uid];
};
setElement = function(uid, element) {
elements[uid] = element;
};
})();
function createListener(uid, handler) {
return {
handler: handler,
wrappedHandler: createWrappedHandler(uid, handler)
};
}
function createWrappedHandler(uid, handler) {
return function(e) {
handler.call(getElement(uid), e || fabric.window.event);
};
}
function createDispatcher(uid, eventName) {
return function(e) {
if (handlers[uid] && handlers[uid][eventName]) {
var handlersForEvent = handlers[uid][eventName];
for (var i = 0, len = handlersForEvent.length; i < len; i++) {
handlersForEvent[i].call(this, e || fabric.window.event);
}
}
};
}
var shouldUseAddListenerRemoveListener = areHostMethods(fabric.document.documentElement, "addEventListener", "removeEventListener") && areHostMethods(fabric.window, "addEventListener", "removeEventListener"), shouldUseAttachEventDetachEvent = areHostMethods(fabric.document.documentElement, "attachEvent", "detachEvent") && areHostMethods(fabric.window, "attachEvent", "detachEvent"), listeners = {}, handlers = {}, addListener, removeListener;
if (shouldUseAddListenerRemoveListener) {
addListener = function(element, eventName, handler) {
element.addEventListener(eventName, handler, false);
};
removeListener = function(element, eventName, handler) {
element.removeEventListener(eventName, handler, false);
};
} else if (shouldUseAttachEventDetachEvent) {
addListener = function(element, eventName, handler) {
var uid = getUniqueId(element);
setElement(uid, element);
if (!listeners[uid]) {
listeners[uid] = {};
}
if (!listeners[uid][eventName]) {
listeners[uid][eventName] = [];
}
var listener = createListener(uid, handler);
listeners[uid][eventName].push(listener);
element.attachEvent("on" + eventName, listener.wrappedHandler);
};
removeListener = function(element, eventName, handler) {
var uid = getUniqueId(element), listener;
if (listeners[uid] && listeners[uid][eventName]) {
for (var i = 0, len = listeners[uid][eventName].length; i < len; i++) {
listener = listeners[uid][eventName][i];
if (listener && listener.handler === handler) {
element.detachEvent("on" + eventName, listener.wrappedHandler);
listeners[uid][eventName][i] = null;
}
}
}
};
} else {
addListener = function(element, eventName, handler) {
var uid = getUniqueId(element);
if (!handlers[uid]) {
handlers[uid] = {};
}
if (!handlers[uid][eventName]) {
handlers[uid][eventName] = [];
var existingHandler = element["on" + eventName];
if (existingHandler) {
handlers[uid][eventName].push(existingHandler);
}
element["on" + eventName] = createDispatcher(uid, eventName);
}
handlers[uid][eventName].push(handler);
};
removeListener = function(element, eventName, handler) {
var uid = getUniqueId(element);
if (handlers[uid] && handlers[uid][eventName]) {
var handlersForEvent = handlers[uid][eventName];
for (var i = 0, len = handlersForEvent.length; i < len; i++) {
if (handlersForEvent[i] === handler) {
handlersForEvent.splice(i, 1);
}
}
}
};
}
fabric.util.addListener = addListener;
fabric.util.removeListener = removeListener;
function getPointer(event) {
event || (event = fabric.window.event);
var element = event.target || (typeof event.srcElement !== unknown ? event.srcElement : null), scroll = fabric.util.getScrollLeftTop(element);
return {
x: pointerX(event) + scroll.left,
y: pointerY(event) + scroll.top
};
}
var pointerX = function(event) {
return typeof event.clientX !== unknown ? event.clientX : 0;
}, pointerY = function(event) {
return typeof event.clientY !== unknown ? event.clientY : 0;
};
function _getPointer(event, pageProp, clientProp) {
var touchProp = event.type === "touchend" ? "changedTouches" : "touches";
return event[touchProp] && event[touchProp][0] ? event[touchProp][0][pageProp] - (event[touchProp][0][pageProp] - event[touchProp][0][clientProp]) || event[clientProp] : event[clientProp];
}
if (fabric.isTouchSupported) {
pointerX = function(event) {
return _getPointer(event, "pageX", "clientX");
};
pointerY = function(event) {
return _getPointer(event, "pageY", "clientY");
};
}
fabric.util.getPointer = getPointer;
fabric.util.object.extend(fabric.util, fabric.Observable);
})();
(function() {
function setStyle(element, styles) {
var elementStyle = element.style;
if (!elementStyle) {
return element;
}
if (typeof styles === "string") {
element.style.cssText += ";" + styles;
return styles.indexOf("opacity") > -1 ? setOpacity(element, styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
}
for (var property in styles) {
if (property === "opacity") {
setOpacity(element, styles[property]);
} else {
var normalizedProperty = property === "float" || property === "cssFloat" ? typeof elementStyle.styleFloat === "undefined" ? "cssFloat" : "styleFloat" : property;
elementStyle[normalizedProperty] = styles[property];
}
}
return element;
}
var parseEl = fabric.document.createElement("div"), supportsOpacity = typeof parseEl.style.opacity === "string", supportsFilters = typeof parseEl.style.filter === "string", reOpacity = /alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/, setOpacity = function(element) {
return element;
};
if (supportsOpacity) {
setOpacity = function(element, value) {
element.style.opacity = value;
return element;
};
} else if (supportsFilters) {
setOpacity = function(element, value) {
var es = element.style;
if (element.currentStyle && !element.currentStyle.hasLayout) {
es.zoom = 1;
}
if (reOpacity.test(es.filter)) {
value = value >= .9999 ? "" : "alpha(opacity=" + value * 100 + ")";
es.filter = es.filter.replace(reOpacity, value);
} else {
es.filter += " alpha(opacity=" + value * 100 + ")";
}
return element;
};
}
fabric.util.setStyle = setStyle;
})();
(function() {
var _slice = Array.prototype.slice;
function getById(id) {
return typeof id === "string" ? fabric.document.getElementById(id) : id;
}
var sliceCanConvertNodelists, toArray = function(arrayLike) {
return _slice.call(arrayLike, 0);
};
try {
sliceCanConvertNodelists = toArray(fabric.document.childNodes) instanceof Array;
} catch (err) {}
if (!sliceCanConvertNodelists) {
toArray = function(arrayLike) {
var arr = new Array(arrayLike.length), i = arrayLike.length;
while (i--) {
arr[i] = arrayLike[i];
}
return arr;
};
}
function makeElement(tagName, attributes) {
var el = fabric.document.createElement(tagName);
for (var prop in attributes) {
if (prop === "class") {
el.className = attributes[prop];
} else if (prop === "for") {
el.htmlFor = attributes[prop];
} else {
el.setAttribute(prop, attributes[prop]);
}
}
return el;
}
function addClass(element, className) {
if (element && (" " + element.className + " ").indexOf(" " + className + " ") === -1) {
element.className += (element.className ? " " : "") + className;
}
}
function wrapElement(element, wrapper, attributes) {
if (typeof wrapper === "string") {
wrapper = makeElement(wrapper, attributes);
}
if (element.parentNode) {
element.parentNode.replaceChild(wrapper, element);
}
wrapper.appendChild(element);
return wrapper;
}
function getScrollLeftTop(element) {
var left = 0, top = 0, docElement = fabric.document.documentElement, body = fabric.document.body || {
scrollLeft: 0,
scrollTop: 0
};
while (element && (element.parentNode || element.host)) {
element = element.parentNode || element.host;
if (element === fabric.document) {
left = body.scrollLeft || docElement.scrollLeft || 0;
top = body.scrollTop || docElement.scrollTop || 0;
} else {
left += element.scrollLeft || 0;
top += element.scrollTop || 0;
}
if (element.nodeType === 1 && fabric.util.getElementStyle(element, "position") === "fixed") {
break;
}
}
return {
left: left,
top: top
};
}
function getElementOffset(element) {
var docElem, doc = element && element.ownerDocument, box = {
left: 0,
top: 0
}, offset = {
left: 0,
top: 0
}, scrollLeftTop, offsetAttributes = {
borderLeftWidth: "left",
borderTopWidth: "top",
paddingLeft: "left",
paddingTop: "top"
};
if (!doc) {
return offset;
}
for (var attr in offsetAttributes) {
offset[offsetAttributes[attr]] += parseInt(getElementStyle(element, attr), 10) || 0;
}
docElem = doc.documentElement;
if (typeof element.getBoundingClientRect !== "undefined") {
box = element.getBoundingClientRect();
}
scrollLeftTop = getScrollLeftTop(element);
return {
left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left,
top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top
};
}
var getElementStyle;
if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) {
getElementStyle = function(element, attr) {
var style = fabric.document.defaultView.getComputedStyle(element, null);
return style ? style[attr] : undefined;
};
} else {
getElementStyle = function(element, attr) {
var value = element.style[attr];
if (!value && element.currentStyle) {
value = element.currentStyle[attr];
}
return value;
};
}
(function() {
var style = fabric.document.documentElement.style, selectProp = "userSelect" in style ? "userSelect" : "MozUserSelect" in style ? "MozUserSelect" : "WebkitUserSelect" in style ? "WebkitUserSelect" : "KhtmlUserSelect" in style ? "KhtmlUserSelect" : "";
function makeElementUnselectable(element) {
if (typeof element.onselectstart !== "undefined") {
element.onselectstart = fabric.util.falseFunction;
}
if (selectProp) {
element.style[selectProp] = "none";
} else if (typeof element.unselectable === "string") {
element.unselectable = "on";
}
return element;
}
function makeElementSelectable(element) {
if (typeof element.onselectstart !== "undefined") {
element.onselectstart = null;
}
if (selectProp) {
element.style[selectProp] = "";
} else if (typeof element.unselectable === "string") {
element.unselectable = "";
}
return element;
}
fabric.util.makeElementUnselectable = makeElementUnselectable;
fabric.util.makeElementSelectable = makeElementSelectable;
})();
(function() {
function getScript(url, callback) {
var headEl = fabric.document.getElementsByTagName("head")[0], scriptEl = fabric.document.createElement("script"), loading = true;
scriptEl.onload = scriptEl.onreadystatechange = function(e) {
if (loading) {
if (typeof this.readyState === "string" && this.readyState !== "loaded" && this.readyState !== "complete") {
return;
}
loading = false;
callback(e || fabric.window.event);
scriptEl = scriptEl.onload = scriptEl.onreadystatechange = null;
}
};
scriptEl.src = url;
headEl.appendChild(scriptEl);
}
fabric.util.getScript = getScript;
})();
fabric.util.getById = getById;
fabric.util.toArray = toArray;
fabric.util.makeElement = makeElement;
fabric.util.addClass = addClass;
fabric.util.wrapElement = wrapElement;
fabric.util.getScrollLeftTop = getScrollLeftTop;
fabric.util.getElementOffset = getElementOffset;
fabric.util.getElementStyle = getElementStyle;
})();
(function() {
function addParamToUrl(url, param) {
return url + (/\?/.test(url) ? "&" : "?") + param;
}
var makeXHR = function() {
var factories = [ function() {
return new ActiveXObject("Microsoft.XMLHTTP");
}, function() {
return new ActiveXObject("Msxml2.XMLHTTP");
}, function() {
return new ActiveXObject("Msxml2.XMLHTTP.3.0");
}, function() {
return new XMLHttpRequest();
} ];
for (var i = factories.length; i--; ) {
try {
var req = factories[i]();
if (req) {
return factories[i];
}
} catch (err) {}
}
}();
function emptyFn() {}
function request(url, options) {
options || (options = {});
var method = options.method ? options.method.toUpperCase() : "GET", onComplete = options.onComplete || function() {}, xhr = makeXHR(), body = options.body || options.parameters;
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
onComplete(xhr);
xhr.onreadystatechange = emptyFn;
}
};
if (method === "GET") {
body = null;
if (typeof options.parameters === "string") {
url = addParamToUrl(url, options.parameters);
}
}
xhr.open(method, url, true);
if (method === "POST" || method === "PUT") {
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
}
xhr.send(body);
return xhr;
}
fabric.util.request = request;
})();
(function() {
var $jscomp = $jscomp || {};
$jscomp.scope = {};
$jscomp.owns = function(d, k) {
return Object.prototype.hasOwnProperty.call(d, k);
};
$jscomp.ASSUME_ES5 = !1;
$jscomp.ASSUME_NO_NATIVE_MAP = !1;
$jscomp.ASSUME_NO_NATIVE_SET = !1;
$jscomp.defineProperty = $jscomp.ASSUME_ES5 || "function" == typeof Object.defineProperties ? Object.defineProperty : function(d, k, e) {
d != Array.prototype && d != Object.prototype && (d[k] = e.value);
};
$jscomp.getGlobal = function(d) {
return "undefined" != typeof window && window === d ? d : "undefined" != typeof global && null != global ? global : d;
};
$jscomp.global = $jscomp.getGlobal(this);
$jscomp.polyfill = function(d, k, e, h) {
if (k) {
e = $jscomp.global;
d = d.split(".");
for (h = 0; h < d.length - 1; h++) {
var q = d[h];
q in e || (e[q] = {});
e = e[q];
}
d = d[d.length - 1];
h = e[d];
k = k(h);
k != h && null != k && $jscomp.defineProperty(e, d, {
configurable: !0,
writable: !0,
value: k
});
}
};
$jscomp.polyfill("Object.assign", function(d) {
return d ? d : function(d, e) {
for (var k = 1; k < arguments.length; k++) {
var q = arguments[k];
if (q) for (var r in q) $jscomp.owns(q, r) && (d[r] = q[r]);
}
return d;
};
}, "es6-impl", "es3");
$jscomp.SYMBOL_PREFIX = "jscomp_symbol_";
$jscomp.initSymbol = function() {
$jscomp.initSymbol = function() {};
$jscomp.global.Symbol || ($jscomp.global.Symbol = $jscomp.Symbol);
};
$jscomp.symbolCounter_ = 0;
$jscomp.Symbol = function(d) {
return $jscomp.SYMBOL_PREFIX + (d || "") + $jscomp.symbolCounter_++;
};
$jscomp.initSymbolIterator = function() {
$jscomp.initSymbol();
var d = $jscomp.global.Symbol.iterator;
d || (d = $jscomp.global.Symbol.iterator = $jscomp.global.Symbol("iterator"));
"function" != typeof Array.prototype[d] && $jscomp.defineProperty(Array.prototype, d, {
configurable: !0,
writable: !0,
value: function() {
return $jscomp.arrayIterator(this);
}
});
$jscomp.initSymbolIterator = function() {};
};
$jscomp.arrayIterator = function(d) {
var k = 0;
return $jscomp.iteratorPrototype(function() {
return k < d.length ? {
done: !1,
value: d[k++]
} : {
done: !0
};
});
};
$jscomp.iteratorPrototype = function(d) {
$jscomp.initSymbolIterator();
d = {
next: d
};
d[$jscomp.global.Symbol.iterator] = function() {
return this;
};
return d;
};
$jscomp.polyfill("Array.from", function(d) {
return d ? d : function(d, e, h) {
$jscomp.initSymbolIterator();
e = null != e ? e : function(d) {
return d;
};
var k = [], r = d[Symbol.iterator];
if ("function" == typeof r) for (d = r.call(d); !(r = d.next()).done; ) k.push(e.call(h, r.value)); else for (var r = d.length, K = 0; K < r; K++) k.push(e.call(h, d[K]));
return k;
};
}, "es6-impl", "es3");
$jscomp.iteratorFromArray = function(d, k) {
$jscomp.initSymbolIterator();
d instanceof String && (d += "");
var e = 0, h = {
next: function() {
if (e < d.length) {
var q = e++;
return {
value: k(q, d[q]),
done: !1
};
}
h.next = function() {
return {
done: !0,
value: void 0
};
};
return h.next();
}
};
h[Symbol.iterator] = function() {
return h;
};
return h;
};
$jscomp.polyfill("Array.prototype.keys", function(d) {
return d ? d : function() {
return $jscomp.iteratorFromArray(this, function(d) {
return d;
});
};
}, "es6-impl", "es3");
$jscomp.polyfill("Object.is", function(d) {
return d ? d : function(d, e) {
return d === e ? 0 !== d || 1 / d === 1 / e : d !== d && e !== e;
};
}, "es6-impl", "es3");
$jscomp.polyfill("Array.prototype.includes", function(d) {
return d ? d : function(d, e) {
var h = this;
h instanceof String && (h = String(h));
var k = h.length;
for (e = e || 0; e < k; e++) if (h[e] == d || Object.is(h[e], d)) return !0;
return !1;
};
}, "es7", "es3");
$jscomp.checkStringArgs = function(d, k, e) {
if (null == d) throw new TypeError("The 'this' value for String.prototype." + e + " must not be null or undefined");
if (k instanceof RegExp) throw new TypeError("First argument to String.prototype." + e + " must not be a regular expression");
return d + "";
};
$jscomp.polyfill("String.prototype.includes", function(d) {
return d ? d : function(d, e) {
return -1 !== $jscomp.checkStringArgs(this, d, "includes").indexOf(d, e || 0);
};
}, "es6-impl", "es3");
$jscomp.polyfill("Array.prototype.fill", function(d) {
return d ? d : function(d, e, h) {
var k = this.length || 0;
0 > e && (e = Math.max(0, k + e));
if (null == h || h > k) h = k;
h = Number(h);
0 > h && (h = Math.max(0, k + h));
for (e = Number(e || 0); e < h; e++) this[e] = d;
return this;
};
}, "es6-impl", "es3");
(function() {
function d(a, b) {
var c = [];
for (a = a[b]; a && 9 !== a.nodeType; ) 1 === a.nodeType && c.push(k(a)), a = a[b];
return c;
}
function k(a) {
return {
el: a,
getClass: function() {
return this.el.getAttribute("class") || "";
},
getClasses: function() {
return this.getClass().split(" ").map(function(a) {
return a.replace(/^\s\s*/, "").replace(/\s\s*$/, "");
}).filter(function(a) {
return 0 < a.length;
});
},
prevAll: function() {
return d(this.el, "previousSibling");
},
nextAll: function() {
return d(this.el, "nextSibling");
},
parent: function() {
return this.el.parentNode && 11 !== this.el.parentNode.nodeType ? k(this.el.parentNode) : null;
}
};
}
function e(a) {
return "string" === typeof a && null !== a.match(/^[a-zA-Z0-9]+$/gi) ? a : !1;
}
function h(a) {
return "string" === typeof a && null !== a.match(/^\.?[a-zA-Z_\-:0-9]*$/gi) ? a : !1;
}
function q(a) {
var b = "undefined" === typeof a ? "undefined" : l(a);
return !!a && ("object" == b || "function" == b);
}
function r(a) {
if ("number" == typeof a) return a;
var b = a;
if ("symbol" == ("undefined" === typeof b ? "undefined" : l(b)) || b && "object" == ("undefined" === typeof b ? "undefined" : l(b)) && "[object Symbol]" == Ha.call(b)) return W;
q(a) && (a = "function" == typeof a.valueOf ? a.valueOf() : a, a = q(a) ? a + "" : a);
if ("string" != typeof a) return 0 === a ? a : +a;
a = a.replace(Ia, "");
return (b = Ja.test(a)) || Ka.test(a) ? La(a.slice(2), b ? 2 : 8) : Ma.test(a) ? W : +a;
}
function K(a, b, c) {
switch (c.length) {
case 0:
return a.call(b);
case 1:
return a.call(b, c[0]);
case 2:
return a.call(b, c[0], c[1]);
case 3:
return a.call(b, c[0], c[1], c[2]);
}
return a.apply(b, c);
}
function Ga(a, b) {
var c;
if (c = !(!a || !a.length)) {
a: if (b !== b) b: {
b = Na;
c = a.length;
for (var g = -1; ++g < c; ) if (b(a[g], g, a)) {
a = g;
break b;
}
a = -1;
} else {
c = -1;
for (g = a.length; ++c < g; ) if (a[c] === b) {
a = c;
break a;
}
a = -1;
}
c = -1 < a;
}
return c;
}
function Na(a) {
return a !== a;
}
function Oa(a, b) {
return a.has(b);
}
function Pa(a) {
var b = !1;
if (null != a && "function" != typeof a.toString) try {
b = !!(a + "");
} catch (c) {}
return b;
}
function x(a) {
var b = -1, c = a ? a.length : 0;
for (this.clear(); ++b < c; ) {
var g = a[b];
this.set(g[0], g[1]);
}
}
function C(a) {
var b = -1, c = a ? a.length : 0;
for (this.clear(); ++b < c; ) {
var g = a[b];
this.set(g[0], g[1]);
}
}
function D(a) {
var b = -1, c = a ? a.length : 0;
for (this.clear(); ++b < c; ) {
var g = a[b];
this.set(g[0], g[1]);
}
}
function N(a) {
var b = -1, c = a ? a.length : 0;
for (this.__data__ = new D(); ++b < c; ) this.add(a[b]);
}
function O(a, b) {
for (var c = a.length; c--; ) {
var g = a[c][0];
if (g === b || g !== g && b !== b) return c;
}
return -1;
}
function X(a, b, c, g, d) {
var u = -1, e = a.length;
c || (c = Qa);
for (d || (d = []); ++u < e; ) {
var k = a[u];
if (0 < b && c(k)) if (1 < b) X(k, b - 1, c, g, d); else for (var h = d, l = -1, v = k.length, z = h.length; ++l < v; ) h[z + l] = k[l]; else g || (d[d.length] = k);
}
return d;
}
function P(a, b) {
a = a.__data__;
var c = "undefined" === typeof b ? "undefined" : l(b);
return ("string" == c || "number" == c || "symbol" == c || "boolean" == c ? "__proto__" !== b : null === b) ? a["string" == typeof b ? "string" : "hash"] : a.map;
}
function Y(a, b) {
a = null == a ? void 0 : a[b];
b = !Z(a) || ma && ma in a ? !1 : (aa(a) || Pa(a) ? Ra : Sa).test(Ta(a));
return b ? a : void 0;
}
function Qa(a) {
var b;
(b = kb(a)) || (b = Q(a) && R.call(a, "callee") && (!lb.call(a, "callee") || "[object Arguments]" == na.call(a)));
return b || !!(oa && a && a[oa]);
}
function Ta(a) {
if (null != a) {
try {
return pa.call(a);
} catch (b) {}
return a + "";
}
return "";
}
function Q(a) {
var b;
if (b = !!a && "object" == ("undefined" === typeof a ? "undefined" : l(a))) {
if (b = null != a) b = a.length, b = "number" == typeof b && -1 < b && 0 == b % 1 && 9007199254740991 >= b;
b = b && !aa(a);
}
return b;
}
function aa(a) {
a = Z(a) ? na.call(a) : "";
return "[object Function]" == a || "[object GeneratorFunction]" == a;
}
function Z(a) {
var b = "undefined" === typeof a ? "undefined" : l(a);
return !!a && ("object" == b || "function" == b);
}
function mb(a, b) {
return 0 < nb(a.getClasses(), ob(b, function(a) {
return a.getClasses();
})).length || !pb(b).includes(a.el.nodeName);
}
function qa(a) {
var b = "undefined" === typeof a ? "undefined" : l(a);
return !!a && ("object" == b || "function" == b);
}
function qb(a) {
if ("number" == typeof a) return a;
var b = a;
if ("symbol" == ("undefined" === typeof b ? "undefined" : l(b)) || b && "object" == ("undefined" === typeof b ? "undefined" : l(b)) && "[object Symbol]" == rb.call(b)) return ra;
qa(a) && (a = "function" == typeof a.valueOf ? a.valueOf() : a, a = qa(a) ? a + "" : a);
if ("string" != typeof a) return 0 === a ? a : +a;
a = a.replace(sb, "");
return (b = tb.test(a)) || ub.test(a) ? vb(a.slice(2), b ? 2 : 8) : wb.test(a) ? ra : +a;
}
function xb(a) {
var b = a.getMethods();
return {
finished: function() {
return 0 === b.length;
},
next: function() {
return this.finished() ? !1 : b.shift().apply(void 0, arguments);
}
};
}
function yb(a, b) {
if (0 >= b) throw Error("Simmer: An invalid depth of " + b + " has been specified");
return Array(b - 1).fill().reduce(function(a, b) {
a[a.length - 1].parent() && (b = a[a.length - 1].parent(), a.push(b));
return a;
}, [ a ]);
}
function sa() {
return ta({}, zb, 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {});
}
function ba() {
function a(a, b) {
if (!0 === g.errorHandling) throw a;
"function" === typeof g.errorHandling && g.errorHandling(a, b);
}
var b = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : window, c = 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : !1, g = sa(1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {}), d = c || ua(b, g.queryEngine), c = function eb(b) {
if (!b) return a.call(eb, Error("Simmer: No element was specified for parsing."), b),
!1;
for (var c = new xb(w), u = yb(k(b), g.depth), e = {
stack: Array(u.length).fill().map(function() {
return [];
}),
specificity: 0
}, h = Ab(b, g, d, a); !c.finished() && !e.verified; ) try {
e = c.next(u, e, h, g, d), e.specificity >= g.specificityThreshold && !e.verified && (e.verified = h(e));
} catch (Bb) {
a.call(eb, Bb, b);
}
if (void 0 === e.verified || e.specificity < g.specificityThreshold) e.verified = h(e);
return e.verified ? e.verificationDepth ? S(e, e.verificationDepth) : S(e) : !1;
};
c.configure = function() {
var a = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : b, c = sa(ta({}, g, 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}));
return ba(a, c, ua(a, c.queryEngine));
};
return c;
}
var Cb = {
querySelectorAll: function() {
throw Error("An invalid context has been provided to Simmer, it doesnt know how to query it");
}
}, Db = function(a) {
var b = "function" === typeof a.querySelectorAll ? a : a.document ? a.document : Cb;
return function(a, g) {
try {
return b.querySelectorAll(a);
} catch (u) {
g(u);
}
};
}, ua = function(a, b) {
var c = "function" === typeof b ? b : Db(a);
return function(b, d) {
return "string" !== typeof b ? [] : c(b, d, a);
};
}, l = "function" === typeof Symbol && "symbol" === typeof Symbol.iterator ? function(a) {
return typeof a;
} : function(a) {
return a && "function" === typeof Symbol && a.constructor === Symbol && a !== Symbol.prototype ? "symbol" : typeof a;
}, ta = Object.assign || function(a) {
for (var b = 1; b < arguments.length; b++) {
var c = arguments[b], d;
for (d in c) Object.prototype.hasOwnProperty.call(c, d) && (a[d] = c[d]);
}
return a;
}, Eb = function() {
return function(a, b) {
if (Array.isArray(a)) return a;
if (Symbol.iterator in Object(a)) {
var c = [], d = !0, e = !1, k = void 0;
try {
for (var h = a[Symbol.iterator](), l; !(d = (l = h.next()).done) && (c.push(l.value),
!b || c.length !== b); d = !0) ;
} catch (B) {
e = !0, k = B;
} finally {
try {
if (!d && h["return"]) h["return"]();
} finally {
if (e) throw k;
}
}
return c;
}
throw new TypeError("Invalid attempt to destructure non-iterable instance");
};
}(), ca = function(a) {
if (Array.isArray(a)) {
for (var b = 0, c = Array(a.length); b < a.length; b++) c[b] = a[b];
return c;
}
return Array.from(a);
}, da = 1 / 0, W = 0 / 0, Ia = /^\s+|\s+$/g, Ma = /^[-+]0x[0-9a-f]+$/i, Ja = /^0b[01]+$/i, Ka = /^0o[0-7]+$/i, La = parseInt, Ha = Object.prototype.toString, Fb = function(a, b, c) {
if (!a || !a.length) return [];
c || void 0 === b ? c = 1 : ((c = b) ? (c = r(c), c = c === da || c === -da ? 17976931348623157e292 * (0 > c ? -1 : 1) : c === c ? c : 0) : c = 0 === c ? c : 0,
b = c % 1, c = c === c ? b ? c - b : c : 0);
b = c;
c = 0;
var d = 0 > b ? 0 : b;
b = -1;
var e = a.length;
0 > c && (c = -c > e ? 0 : e + c);
d = d > e ? e : d;
0 > d && (d += e);
e = c > d ? 0 : d - c >>> 0;
c >>>= 0;
for (d = Array(e); ++b < e; ) d[b] = a[b + c];
return d;
}, H = "undefined" !== typeof window ? window : "undefined" !== typeof global ? global : "undefined" !== typeof self ? self : {}, Sa = /^\[object .+?Constructor\]$/, y = "object" == l(H) && H && H.Object === Object && H, ea = "object" == ("undefined" === typeof self ? "undefined" : l(self)) && self && self.Object === Object && self, y = y || ea || Function("return this")(), ea = Array.prototype, T = Function.prototype, fa = Object.prototype, ga = y["__core-js_shared__"], ma = function() {
var a = /[^.]+$/.exec(ga && ga.keys && ga.keys.IE_PROTO || "");
return a ? "Symbol(src)_1." + a : "";
}(), pa = T.toString, R = fa.hasOwnProperty, na = fa.toString, Ra = RegExp("^" + pa.call(R).replace(/[\\^$.*+?()[\]{}|]/g, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$"), T = y.Symbol, lb = fa.propertyIsEnumerable, Gb = ea.splice, oa = T ? T.isConcatSpreadable : void 0, ha = Math.max, Hb = Y(y, "Map"), L = Y(Object, "create");
x.prototype.clear = function() {
this.__data__ = L ? L(null) : {};
};
x.prototype["delete"] = function(a) {
return this.has(a) && delete this.__data__[a];
};
x.prototype.get = function(a) {
var b = this.__data__;
return L ? (a = b[a], "__lodash_hash_undefined__" === a ? void 0 : a) : R.call(b, a) ? b[a] : void 0;
};
x.prototype.has = function(a) {
var b = this.__data__;
return L ? void 0 !== b[a] : R.call(b, a);
};
x.prototype.set = function(a, b) {
this.__data__[a] = L && void 0 === b ? "__lodash_hash_undefined__" : b;
return this;
};
C.prototype.clear = function() {
this.__data__ = [];
};
C.prototype["delete"] = function(a) {
var b = this.__data__;
a = O(b, a);
if (0 > a) return !1;
a == b.length - 1 ? b.pop() : Gb.call(b, a, 1);
return !0;
};
C.prototype.get = function(a) {
var b = this.__data__;
a = O(b, a);
return 0 > a ? void 0 : b[a][1];
};
C.prototype.has = function(a) {
return -1 < O(this.__data__, a);
};
C.prototype.set = function(a, b) {
var c = this.__data__, d = O(c, a);
0 > d ? c.push([ a, b ]) : c[d][1] = b;
return this;
};
D.prototype.clear = function() {
this.__data__ = {
hash: new x(),
map: new (Hb || C)(),
string: new x()
};
};
D.prototype["delete"] = function(a) {
return P(this, a)["delete"](a);
};
D.prototype.get = function(a) {
return P(this, a).get(a);
};
D.prototype.has = function(a) {
return P(this, a).has(a);
};
D.prototype.set = function(a, b) {
P(this, a).set(a, b);
return this;
};
N.prototype.add = N.prototype.push = function(a) {
this.__data__.set(a, "__lodash_hash_undefined__");
return this;
};
N.prototype.has = function(a) {
return this.__data__.has(a);
};
var y = function(a, b) {
b = ha(void 0 === b ? a.length - 1 : b, 0);
return function() {
for (var c = arguments, d = -1, e = ha(c.length - b, 0), h = Array(e); ++d < e; ) h[d] = c[b + d];
d = -1;
for (e = Array(b + 1); ++d < b; ) e[d] = c[d];
e[b] = h;
return K(a, this, e);
};
}(function(a, b) {
if (Q(a)) {
b = X(b, 1, Q, !0);
var c = -1, d = Ga, e = !0, h = a.length, k = [], l = b.length;
if (h) b: for (200 <= b.length && (d = Oa, e = !1, b = new N(b)); ++c < h; ) {
var B = a[c], q = B, B = 0 !== B ? B : 0;
if (e && q === q) {
for (var v = l; v--; ) if (b[v] === q) continue b;
k.push(B);
} else d(b, q, void 0) || k.push(B);
}
a = k;
} else a = [];
return a;
}), kb = Array.isArray, nb = y, ob = function(a, b) {
return b = {
exports: {}
}, a(b, b.exports), b.exports;
}(function(a, b) {
function c(f, a) {
for (var b = -1, m = f ? f.length : 0, c = Array(m); ++b < m; ) c[b] = a(f[b], b, f);
return c;
}
function d(a, b) {
for (var f = -1, m = a ? a.length : 0; ++f < m; ) if (b(a[f], f, a)) return !0;
return !1;
}
function e(a) {
return function(f) {
return null == f ? void 0 : f[a];
};
}
function h(a) {
return function(f) {
return a(f);
};
}
function k(a) {
var f = !1;
if (null != a && "function" != typeof a.toString) try {
f = !!(a + "");
} catch (p) {}
return f;
}
function q(a) {
var f = -1, b = Array(a.size);
a.forEach(function(a, m) {
b[++f] = [ m, a ];
});
return b;
}
function B(a) {
var f = -1, b = Array(a.size);
a.forEach(function(a) {
b[++f] = a;
});
return b;
}
function r(a) {
var f = -1, b = a ? a.length : 0;
for (this.clear(); ++f < b; ) {
var c = a[f];
this.set(c[0], c[1]);
}
}
function v(a) {
var f = -1, b = a ? a.length : 0;
for (this.clear(); ++f < b; ) {
var c = a[f];
this.set(c[0], c[1]);
}
}
function z(a) {
var f = -1, b = a ? a.length : 0;
for (this.clear(); ++f < b; ) {
var c = a[f];
this.set(c[0], c[1]);
}
}
function x(a) {
var f = -1, b = a ? a.length : 0;
for (this.__data__ = new z(); ++f < b; ) this.add(a[f]);
}
function E(a) {
this.__data__ = new v(a);
}
function y(a, b) {
for (var f = a.length; f--; ) if (Y(a[f][0], b)) return f;
return -1;
}
function C(a, b, c, d, e) {
var f = -1, m = a.length;
c || (c = ga);
for (e || (e = []); ++f < m; ) {
var p = a[f];
if (0 < b && c(p)) if (1 < b) C(p, b - 1, c, d, e); else for (var t = e, g = -1, h = p.length, k = t.length; ++g < h; ) t[k + g] = p[g]; else d || (e[e.length] = p);
}
return e;
}
function D(a, b) {
b = wa(b, a) ? [ b ] : Q(b);
for (var f = 0, m = b.length; null != a && f < m; ) a = a[xa(b[f++])];
return f && f == m ? a : void 0;
}
function w(a, b, c, d, e) {
if (a === b) return !0;
if (null == a || null == b || !ia(a) && !ya(b)) return a !== a && b !== b;
a: {
var f = F(a), m = F(b), p = "[object Array]", g = "[object Array]";
f || (p = I(a), p = "[object Arguments]" == p ? "[object Object]" : p);
m || (g = I(b), g = "[object Arguments]" == g ? "[object Object]" : g);
var t = "[object Object]" == p && !k(a), m = "[object Object]" == g && !k(b);
if ((g = p == g) && !t) e || (e = new E()), b = f || Ta(a) ? S(a, b, w, c, d, e) : ea(a, b, p, w, c, d, e); else {
if (!(d & 2) && (f = t && G.call(a, "__wrapped__"), p = m && G.call(b, "__wrapped__"),
f || p)) {
a = f ? a.value() : a;
b = p ? b.value() : b;
e || (e = new E());
b = w(a, b, c, d, e);
break a;
}
if (g) {
e || (e = new E());
b: {
var h, f = d & 2, p = za(a), m = p.length, g = za(b).length;
if (m == g || f) {
for (t = m; t--; ) {
var A = p[t];
if (!(f ? A in b : G.call(b, A))) {
b = !1;
break b;
}
}
if ((g = e.get(a)) && e.get(b)) b = g == b; else {
g = !0;
e.set(a, b);
e.set(b, a);
for (var u = f; ++t < m; ) {
A = p[t];
var l = a[A], n = b[A];
c && (h = f ? c(n, l, A, b, a, e) : c(l, n, A, a, b, e));
if (void 0 === h ? l !== n && !w(l, n, c, d, e) : !h) {
g = !1;
break;
}
u || (u = "constructor" == A);
}
g && !u && (c = a.constructor, d = b.constructor, c != d && "constructor" in a && "constructor" in b && !("function" == typeof c && c instanceof c && "function" == typeof d && d instanceof d) && (g = !1));
e["delete"](a);
e["delete"](b);
b = g;
}
} else b = !1;
}
} else b = !1;
}
}
return b;
}
function K(a, b, c, d) {
var f, m = c.length, e = m, p = !d;
if (null == a) return !e;
for (a = Object(a); m--; ) {
var g = c[m];
if (p && g[2] ? g[1] !== a[g[0]] : !(g[0] in a)) return !1;
}
for (;++m < e; ) {
g = c[m];
var t = g[0], h = a[t], k = g[1];
if (p && g[2]) {
if (void 0 === h && !(t in a)) return !1;
} else if (g = new E(), d && (f = d(h, k, t, a, b, g)), void 0 === f ? !w(k, h, d, 3, g) : !f) return !1;
}
return !0;
}
function L(a) {
return ya(a) && Ua(a.length) && !!n[U.call(a)];
}
function N(a, b) {
var f = -1, c = Aa(a) ? Array(a.length) : [];
Qa(a, function(a, m, d) {
c[++f] = b(a, m, d);
});
return c;
}
function O(a) {
var b = fa(a);
return 1 == b.length && b[0][2] ? X(b[0][0], b[0][1]) : function(f) {
return f === a || K(f, a, b);
};
}
function P(a, b) {
return wa(a) && b === b && !ia(b) ? X(xa(a), b) : function(f) {
var c = null == f ? void 0 : D(f, a);
c = void 0 === c ? void 0 : c;
if (void 0 === c && c === b) {
if (c = null != f) {
c = a;
c = wa(c, f) ? [ c ] : Q(c);
for (var m, d = -1, e = c.length; ++d < e; ) {
var g = xa(c[d]);
if (!(m = null != f && null != f && g in Object(f))) break;
f = f[g];
}
m ? c = m : (e = f ? f.length : 0, c = !!e && Ua(e) && W(g, e) && (F(f) || Va(f)));
}
g = c;
} else g = w(b, c, void 0, 3);
return g;
};
}
function R(a) {
return function(b) {
return D(b, a);
};
}
function T(a) {
if ("string" == typeof a) return a;
if (Wa(a)) return fb ? fb.call(a) : "";
var b = a + "";
return "0" == b && 1 / a == -aa ? "-0" : b;
}
function Q(a) {
return F(a) ? a : Sa(a);
}
function S(a, b, c, e, g, h) {
var f, m = g & 2, p = a.length, k = b.length;
if (p != k && !(m && k > p)) return !1;
if ((k = h.get(a)) && h.get(b)) return k == b;
var k = -1, t = !0, u = g & 1 ? new x() : void 0;
h.set(a, b);
for (h.set(b, a); ++k < p; ) {
var l = a[k], va = b[k];
e && (f = m ? e(va, l, k, b, a, h) : e(l, va, k, a, b, h));
if (void 0 !== f) {
if (f) continue;
t = !1;
break;
}
if (u) {
if (!d(b, function(a, b) {
if (!u.has(b) && (l === a || c(l, a, e, g, h))) return u.add(b);
})) {
t = !1;
break;
}
} else if (l !== va && !c(l, va, e, g, h)) {
t = !1;
break;
}
}
h["delete"](a);
h["delete"](b);
return t;
}
function ea(a, b, c, d, e, g, h) {
switch (c) {
case "[object DataView]":
if (a.byteLength != b.byteLength || a.byteOffset != b.byteOffset) break;
a = a.buffer;
b = b.buffer;
case "[object ArrayBuffer]":
if (a.byteLength != b.byteLength || !d(new gb(a), new gb(b))) break;
return !0;
case "[object Boolean]":
case "[object Date]":
case "[object Number]":
return Y(+a, +b);
case "[object Error]":
return a.name == b.name && a.message == b.message;
case "[object RegExp]":
case "[object String]":
return a == b + "";
case "[object Map]":
var f = q;
case "[object Set]":
f || (f = B);
if (a.size != b.size && !(g & 2)) break;
if (c = h.get(a)) return c == b;
g |= 1;
h.set(a, b);
b = S(f(a), f(b), d, e, g, h);
h["delete"](a);
return b;
case "[object Symbol]":
if (Xa) return Xa.call(a) == Xa.call(b);
}
return !1;
}
function Ba(a, b) {
a = a.__data__;
var f = "undefined" === typeof b ? "undefined" : l(b);
return ("string" == f || "number" == f || "symbol" == f || "boolean" == f ? "__proto__" !== b : null === b) ? a["string" == typeof b ? "string" : "hash"] : a.map;
}
function fa(a) {
for (var b = za(a), f = b.length; f--; ) {
var c = b[f], d = a[c];
b[f] = [ c, d, d === d && !ia(d) ];
}
return b;
}
function V(a, b) {
a = null == a ? void 0 : a[b];
b = !ia(a) || hb && hb in a ? !1 : (Z(a) || k(a) ? Ha : sa).test(M(a));
return b ? a : void 0;
}
function ga(a) {
return F(a) || Va(a) || !!(ib && a && a[ib]);
}
function W(a, b) {
b = null == b ? 9007199254740991 : b;
return !!b && ("number" == typeof a || ta.test(a)) && -1 < a && 0 == a % 1 && a < b;
}
function wa(a, b) {
if (F(a)) return !1;
var f = "undefined" === typeof a ? "undefined" : l(a);
return "number" == f || "symbol" == f || "boolean" == f || null == a || Wa(a) ? !0 : oa.test(a) || !na.test(a) || null != b && a in Object(b);
}
function X(a, b) {
return function(f) {
return null == f ? !1 : f[a] === b && (void 0 !== b || a in Object(f));
};
}
function xa(a) {
if ("string" == typeof a || Wa(a)) return a;
var b = a + "";
return "0" == b && 1 / a == -aa ? "-0" : b;
}
function M(a) {
if (null != a) {
try {
return jb.call(a);
} catch (m) {}
return a + "";
}
return "";
}
function Ya(a, b) {
if ("function" != typeof a || b && "function" != typeof b) throw new TypeError("Expected a function");
var f = function A() {
var f = arguments, c = b ? b.apply(this, f) : f[0], d = A.cache;
if (d.has(c)) return d.get(c);
f = a.apply(this, f);
A.cache = d.set(c, f);
return f;
};
f.cache = new (Ya.Cache || z)();
return f;
}
function Y(a, b) {
return a === b || a !== a && b !== b;
}
function Va(a) {
return ya(a) && Aa(a) && G.call(a, "callee") && (!Ia.call(a, "callee") || "[object Arguments]" == U.call(a));
}
function Aa(a) {
return null != a && Ua(a.length) && !Z(a);
}
function Z(a) {
a = ia(a) ? U.call(a) : "";
return "[object Function]" == a || "[object GeneratorFunction]" == a;
}
function Ua(a) {
return "number" == typeof a && -1 < a && 0 == a % 1 && 9007199254740991 >= a;
}
function ia(a) {
var b = "undefined" === typeof a ? "undefined" : l(a);
return !!a && ("object" == b || "function" == b);
}
function ya(a) {
return !!a && "object" == ("undefined" === typeof a ? "undefined" : l(a));
}
function Wa(a) {
return "symbol" == ("undefined" === typeof a ? "undefined" : l(a)) || ya(a) && "[object Symbol]" == U.call(a);
}
function za(a) {
if (Aa(a)) {
if (F(a) || Va(a)) {
var b = a.length;
for (var c = String, f = -1, d = Array(b); ++f < b; ) d[f] = c(f);
b = d;
} else b = [];
var c = b.length, f = !!c;
for (e in a) !G.call(a, e) || f && ("length" == e || W(e, c)) || b.push(e);
a = b;
} else {
var e = a && a.constructor;
if (a === ("function" == typeof e && e.prototype || Ca)) {
e = [];
for (b in Object(a)) G.call(a, b) && "constructor" != b && e.push(b);
a = e;
} else a = Ka(a);
}
return a;
}
function ma(a) {
return a;
}
var aa = 1 / 0, na = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, oa = /^\w*$/, pa = /^\./, qa = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g, ra = /\\(\\)?/g, sa = /^\[object .+?Constructor\]$/, ta = /^(?:0|[1-9]\d*)$/, n = {};
n["[object Float32Array]"] = n["[object Float64Array]"] = n["[object Int8Array]"] = n["[object Int16Array]"] = n["[object Int32Array]"] = n["[object Uint8Array]"] = n["[object Uint8ClampedArray]"] = n["[object Uint16Array]"] = n["[object Uint32Array]"] = !0;
n["[object Arguments]"] = n["[object Array]"] = n["[object ArrayBuffer]"] = n["[object Boolean]"] = n["[object DataView]"] = n["[object Date]"] = n["[object Error]"] = n["[object Function]"] = n["[object Map]"] = n["[object Number]"] = n["[object Object]"] = n["[object RegExp]"] = n["[object Set]"] = n["[object String]"] = n["[object WeakMap]"] = !1;
var ba = "object" == l(H) && H && H.Object === Object && H, ua = "object" == ("undefined" === typeof self ? "undefined" : l(self)) && self && self.Object === Object && self, J = ba || ua || Function("return this")(), ca = b && !b.nodeType && b, da = ca && !0 && a && !a.nodeType && a, ha = da && da.exports === ca && ba.process;
a: {
try {
var Za = ha && ha.binding("util");
break a;
} catch (f) {}
Za = void 0;
}
var la = Za && Za.isTypedArray, Fa = Array.prototype, Ga = Function.prototype, Ca = Object.prototype, $a = J["__core-js_shared__"], hb = function() {
var a = /[^.]+$/.exec($a && $a.keys && $a.keys.IE_PROTO || "");
return a ? "Symbol(src)_1." + a : "";
}(), jb = Ga.toString, G = Ca.hasOwnProperty, U = Ca.toString, Ha = RegExp("^" + jb.call(G).replace(/[\\^$.*+?()[\]{}|]/g, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$"), Da = J.Symbol, gb = J.Uint8Array, Ia = Ca.propertyIsEnumerable, Ja = Fa.splice, ib = Da ? Da.isConcatSpreadable : void 0, Ka = function(a, b) {
return function(c) {
return a(b(c));
};
}(Object.keys, Object), ab = V(J, "DataView"), ja = V(J, "Map"), bb = V(J, "Promise"), cb = V(J, "Set"), db = V(J, "WeakMap"), ka = V(Object, "create"), La = M(ab), Ma = M(ja), Na = M(bb), Oa = M(cb), Pa = M(db), Ea = Da ? Da.prototype : void 0, Xa = Ea ? Ea.valueOf : void 0, fb = Ea ? Ea.toString : void 0;
r.prototype.clear = function() {
this.__data__ = ka ? ka(null) : {};
};
r.prototype["delete"] = function(a) {
return this.has(a) && delete this.__data__[a];
};
r.prototype.get = function(a) {
var b = this.__data__;
return ka ? (a = b[a], "__lodash_hash_undefined__" === a ? void 0 : a) : G.call(b, a) ? b[a] : void 0;
};
r.prototype.has = function(a) {
var b = this.__data__;
return ka ? void 0 !== b[a] : G.call(b, a);
};
r.prototype.set = function(a, b) {
this.__data__[a] = ka && void 0 === b ? "__lodash_hash_undefined__" : b;
return this;
};
v.prototype.clear = function() {
this.__data__ = [];
};
v.prototype["delete"] = function(a) {
var b = this.__data__;
a = y(b, a);
if (0 > a) return !1;
a == b.length - 1 ? b.pop() : Ja.call(b, a, 1);
return !0;
};
v.prototype.get = function(a) {
var b = this.__data__;
a = y(b, a);
return 0 > a ? void 0 : b[a][1];
};
v.prototype.has = function(a) {
return -1 < y(this.__data__, a);
};
v.prototype.set = function(a, b) {
var c = this.__data__, d = y(c, a);
0 > d ? c.push([ a, b ]) : c[d][1] = b;
return this;
};
z.prototype.clear = function() {
this.__data__ = {
hash: new r(),
map: new (ja || v)(),
string: new r()
};
};
z.prototype["delete"] = function(a) {
return Ba(this, a)["delete"](a);
};
z.prototype.get = function(a) {
return Ba(this, a).get(a);
};
z.prototype.has = function(a) {
return Ba(this, a).has(a);
};
z.prototype.set = function(a, b) {
Ba(this, a).set(a, b);
return this;
};
x.prototype.add = x.prototype.push = function(a) {
this.__data__.set(a, "__lodash_hash_undefined__");
return this;
};
x.prototype.has = function(a) {
return this.__data__.has(a);
};
E.prototype.clear = function() {
this.__data__ = new v();
};
E.prototype["delete"] = function(a) {
return this.__data__["delete"](a);
};
E.prototype.get = function(a) {
return this.__data__.get(a);
};
E.prototype.has = function(a) {
return this.__data__.has(a);
};
E.prototype.set = function(a, b) {
var c = this.__data__;
if (c instanceof v) {
c = c.__data__;
if (!ja || 199 > c.length) return c.push([ a, b ]), this;
c = this.__data__ = new z(c);
}
c.set(a, b);
return this;
};
var Qa = function(a, b) {
return function(c, d) {
if (null == c) return c;
if (!Aa(c)) return a(c, d);
for (var f = c.length, e = b ? f : -1, g = Object(c); (b ? e-- : ++e < f) && !1 !== d(g[e], e, g); ) ;
return c;
};
}(function(a, b) {
return a && Ra(a, b, za);
}), Ra = function(a) {
return function(b, c, d) {
var e = -1, f = Object(b);
d = d(b);
for (var g = d.length; g--; ) {
var h = d[a ? g : ++e];
if (!1 === c(f[h], h, f)) break;
}
return b;
};
}(), I = function(a) {
return U.call(a);
};
if (ab && "[object DataView]" != I(new ab(new ArrayBuffer(1))) || ja && "[object Map]" != I(new ja()) || bb && "[object Promise]" != I(bb.resolve()) || cb && "[object Set]" != I(new cb()) || db && "[object WeakMap]" != I(new db())) I = function(a) {
var b = U.call(a);
if (a = (a = "[object Object]" == b ? a.constructor : void 0) ? M(a) : void 0) switch (a) {
case La:
return "[object DataView]";
case Ma:
return "[object Map]";
case Na:
return "[object Promise]";
case Oa:
return "[object Set]";
case Pa:
return "[object WeakMap]";
}
return b;
};
var Sa = Ya(function(a) {
a = null == a ? "" : T(a);
var b = [];
pa.test(a) && b.push("");
a.replace(qa, function(a, c, d, e) {
b.push(d ? e.replace(ra, "$1") : c || a);
});
return b;
});
Ya.Cache = z;
var F = Array.isArray, Ta = la ? h(la) : L;
a.exports = function(a, b) {
var d = F(a) ? c : N;
b = "function" == typeof b ? b : null == b ? ma : "object" == ("undefined" === typeof b ? "undefined" : l(b)) ? F(b) ? P(b[0], b[1]) : O(b) : wa(b) ? e(xa(b)) : R(b);
a = d(a, b);
return C(a, 1);
};
}), pb = function(a) {
return a.map(function(a) {
return a.el.nodeName;
});
}, la = {
A: function(a, b) {
if (b = b.el.getAttribute("href")) a.stack[0].push('A[href="' + b + '"]'), a.specificity += 10;
return a;
},
IMG: function(a, b) {
if (b = b.el.getAttribute("src")) a.stack[0].push('IMG[src="' + b + '"]'), a.specificity += 10;
return a;
}
}, w = {
methods: [],
getMethods: function() {
return this.methods.slice(0);
},
addMethod: function(a) {
this.methods.push(a);
}
};
w.addMethod(function(a, b, c, d, e) {
return a.reduce(function(a, b, g) {
return a.verified ? a : (b = [ b.el.getAttribute("id") ].filter(function(a) {
a = "string" === typeof a && null !== a.match(/^[0-9a-zA-Z][a-zA-Z_\-:0-9.]*$/gi) ? a : !1;
return a;
}).filter(function(a) {
return 1 === (e('[id="' + a + '"]') || []).length;
}).map(function(b) {
a.stack[g].push("[id='" + b + "']");
a.specificity += 100;
a.specificity >= d.specificityThreshold && c(a) && (a.verified = !0);
a.verified || 0 !== g || (a.stack[g].pop(), a.specificity -= 100);
return a;
}), Eb(b, 1)[0] || a);
}, b);
});
w.addMethod(function(a, b) {
return a.reduce(function(a, b, d) {
[ b.el.nodeName ].filter(e).forEach(function(b) {
a.stack[d].splice(0, 0, b);
a.specificity += 10;
});
return a;
}, b);
});
w.addMethod(function(a, b, c) {
a = a[0];
var d = a.el.nodeName;
la[d] && (b = la[d](b, a), c(b) ? b.verified = !0 : b.stack[0].pop());
return b;
});
w.addMethod(function(a, b) {
return a.reduce(function(a, b, d) {
b = Fb(b.getClasses(), 10).filter(h).map(function(a) {
return "." + a;
});
b.length && (a.stack[d].push(b.join("")), a.specificity += 10 * b.length);
return a;
}, b);
});
w.addMethod(function(a, b, c) {
return a.reduce(function(a, b, d) {
if (!a.verified) {
var e = b.prevAll(), g = b.nextAll(), h = e.length + 1;
!e.length && !g.length || mb(b, [].concat(ca(e), ca(g))) || (a.stack[d].push(":nth-child(" + h + ")"),
a.verified = c(a));
}
return a;
}, b);
});
var Fa = 1 / 0, ra = 0 / 0, sb = /^\s+|\s+$/g, wb = /^[-+]0x[0-9a-f]+$/i, tb = /^0b[01]+$/i, ub = /^0o[0-7]+$/i, vb = parseInt, rb = Object.prototype.toString, Ib = function(a, b, c) {
var d = a ? a.length : 0;
if (!d) return [];
c || void 0 === b ? b = 1 : (b ? (b = qb(b), b = b === Fa || b === -Fa ? 17976931348623157e292 * (0 > b ? -1 : 1) : b === b ? b : 0) : b = 0 === b ? b : 0,
c = b % 1, b = b === b ? c ? b - c : b : 0);
b = d - b;
b = 0 > b ? 0 : b;
var e = d, d = -1;
c = a.length;
0 > b && (b = -b > c ? 0 : c + b);
e = e > c ? c : e;
0 > e && (e += c);
c = b > e ? 0 : e - b >>> 0;
b >>>= 0;
for (e = Array(c); ++d < c; ) e[d] = a[d + b];
return e;
}, S = function(a) {
var b = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : a.stack.length;
return Ib(a.stack.reduceRight(function(a, b) {
b.length ? a.push(b.join("")) : a.length && a.push("*");
return a;
}, []), b).join(" > ") || "*";
}, Ab = function(a, b, c, d) {
var e = b.selectorMaxLength;
return function(b) {
for (var g = !1, h = 1; h <= b.stack.length && !g; h += 1) {
g = S(b, h).trim();
if (!g || !g.length || e && g.length > e) return !1;
g = c(g, d);
if (g = 1 === g.length && (void 0 !== a.el ? g[0] === a.el : g[0] === a)) b.verificationDepth = h;
}
return g;
};
}, zb = {
queryEngine: null,
specificityThreshold: 100,
depth: 3,
errorHandling: !1,
selectorMaxLength: 512
};
(function(a, b) {
var c = a.Simmer;
a.Simmer = b;
b.noConflict = function() {
a.Simmer = c;
return b;
};
})(fabric.util, ba(window));
})();
})();
fabric.log = function() {};
fabric.warn = function() {};
if (typeof console !== "undefined") {
[ "log", "warn" ].forEach(function(methodName) {
if (typeof console[methodName] !== "undefined" && typeof console[methodName].apply === "function") {
fabric[methodName] = function() {
return console[methodName].apply(console, arguments);
};
}
});
}
(function() {
function animate(options) {
requestAnimFrame(function(timestamp) {
options || (options = {});
var start = timestamp || +new Date(), duration = options.duration || 500, finish = start + duration, time, onChange = options.onChange || function() {}, abort = options.abort || function() {
return false;
}, easing = options.easing || function(t, b, c, d) {
return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
}, startValue = "startValue" in options ? options.startValue : 0, endValue = "endValue" in options ? options.endValue : 100, byValue = options.byValue || endValue - startValue;
options.onStart && options.onStart();
(function tick(ticktime) {
time = ticktime || +new Date();
var currentTime = time > finish ? duration : time - start;
if (abort()) {
options.onComplete && options.onComplete();
return;
}
onChange(easing(currentTime, startValue, byValue, duration));
if (time > finish) {
options.onComplete && options.onComplete();
return;
}
requestAnimFrame(tick);
})(start);
});
}
var _requestAnimFrame = fabric.window.requestAnimationFrame || fabric.window.webkitRequestAnimationFrame || fabric.window.mozRequestAnimationFrame || fabric.window.oRequestAnimationFrame || fabric.window.msRequestAnimationFrame || function(callback) {
fabric.window.setTimeout(callback, 1e3 / 60);
};
function requestAnimFrame() {
return _requestAnimFrame.apply(fabric.window, arguments);
}
fabric.util.animate = animate;
fabric.util.requestAnimFrame = requestAnimFrame;
})();
(function() {
function normalize(a, c, p, s) {
if (a < Math.abs(c)) {
a = c;
s = p / 4;
} else {
if (c === 0 && a === 0) {
s = p / (2 * Math.PI) * Math.asin(1);
} else {
s = p / (2 * Math.PI) * Math.asin(c / a);
}
}
return {
a: a,
c: c,
p: p,
s: s
};
}
function elastic(opts, t, d) {
return opts.a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p);
}
function easeOutCubic(t, b, c, d) {
return c * ((t = t / d - 1) * t * t + 1) + b;
}
function easeInOutCubic(t, b, c, d) {
t /= d / 2;
if (t < 1) {
return c / 2 * t * t * t + b;
}
return c / 2 * ((t -= 2) * t * t + 2) + b;
}
function easeInQuart(t, b, c, d) {
return c * (t /= d) * t * t * t + b;
}
function easeOutQuart(t, b, c, d) {
return -c * ((t = t / d - 1) * t * t * t - 1) + b;
}
function easeInOutQuart(t, b, c, d) {
t /= d / 2;
if (t < 1) {
return c / 2 * t * t * t * t + b;
}
return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
}
function easeInQuint(t, b, c, d) {
return c * (t /= d) * t * t * t * t + b;
}
function easeOutQuint(t, b, c, d) {
return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
}
function easeInOutQuint(t, b, c, d) {
t /= d / 2;
if (t < 1) {
return c / 2 * t * t * t * t * t + b;
}
return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
}
function easeInSine(t, b, c, d) {
return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
}
function easeOutSine(t, b, c, d) {
return c * Math.sin(t / d * (Math.PI / 2)) + b;
}
function easeInOutSine(t, b, c, d) {
return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
}
function easeInExpo(t, b, c, d) {
return t === 0 ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
}
function easeOutExpo(t, b, c, d) {
return t === d ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
}
function easeInOutExpo(t, b, c, d) {
if (t === 0) {
return b;
}
if (t === d) {
return b + c;
}
t /= d / 2;
if (t < 1) {
return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
}
return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
}
function easeInCirc(t, b, c, d) {
return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
}
function easeOutCirc(t, b, c, d) {
return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
}
function easeInOutCirc(t, b, c, d) {
t /= d / 2;
if (t < 1) {
return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
}
return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
}
function easeInElastic(t, b, c, d) {
var s = 1.70158, p = 0, a = c;
if (t === 0) {
return b;
}
t /= d;
if (t === 1) {
return b + c;
}
if (!p) {
p = d * .3;
}
var opts = normalize(a, c, p, s);
return -elastic(opts, t, d) + b;
}
function easeOutElastic(t, b, c, d) {
var s = 1.70158, p = 0, a = c;
if (t === 0) {
return b;
}
t /= d;
if (t === 1) {
return b + c;
}
if (!p) {
p = d * .3;
}
var opts = normalize(a, c, p, s);
return opts.a * Math.pow(2, -10 * t) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p) + opts.c + b;
}
function easeInOutElastic(t, b, c, d) {
var s = 1.70158, p = 0, a = c;
if (t === 0) {
return b;
}
t /= d / 2;
if (t === 2) {
return b + c;
}
if (!p) {
p = d * (.3 * 1.5);
}
var opts = normalize(a, c, p, s);
if (t < 1) {
return -.5 * elastic(opts, t, d) + b;
}
return opts.a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p) * .5 + opts.c + b;
}
function easeInBack(t, b, c, d, s) {
if (s === undefined) {
s = 1.70158;
}
return c * (t /= d) * t * ((s + 1) * t - s) + b;
}
function easeOutBack(t, b, c, d, s) {
if (s === undefined) {
s = 1.70158;
}
return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
}
function easeInOutBack(t, b, c, d, s) {
if (s === undefined) {
s = 1.70158;
}
t /= d / 2;
if (t < 1) {
return c / 2 * (t * t * (((s *= 1.525) + 1) * t - s)) + b;
}
return c / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b;
}
function easeInBounce(t, b, c, d) {
return c - easeOutBounce(d - t, 0, c, d) + b;
}
function easeOutBounce(t, b, c, d) {
if ((t /= d) < 1 / 2.75) {
return c * (7.5625 * t * t) + b;
} else if (t < 2 / 2.75) {
return c * (7.5625 * (t -= 1.5 / 2.75) * t + .75) + b;
} else if (t < 2.5 / 2.75) {
return c * (7.5625 * (t -= 2.25 / 2.75) * t + .9375) + b;
} else {
return c * (7.5625 * (t -= 2.625 / 2.75) * t + .984375) + b;
}
}
function easeInOutBounce(t, b, c, d) {
if (t < d / 2) {
return easeInBounce(t * 2, 0, c, d) * .5 + b;
}
return easeOutBounce(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
}
fabric.util.ease = {
easeInQuad: function(t, b, c, d) {
return c * (t /= d) * t + b;
},
easeOutQuad: function(t, b, c, d) {
return -c * (t /= d) * (t - 2) + b;
},
easeInOutQuad: function(t, b, c, d) {
t /= d / 2;
if (t < 1) {
return c / 2 * t * t + b;
}
return -c / 2 * (--t * (t - 2) - 1) + b;
},
easeInCubic: function(t, b, c, d) {
return c * (t /= d) * t * t + b;
},
easeOutCubic: easeOutCubic,
easeInOutCubic: easeInOutCubic,
easeInQuart: easeInQuart,
easeOutQuart: easeOutQuart,
easeInOutQuart: easeInOutQuart,
easeInQuint: easeInQuint,
easeOutQuint: easeOutQuint,
easeInOutQuint: easeInOutQuint,
easeInSine: easeInSine,
easeOutSine: easeOutSine,
easeInOutSine: easeInOutSine,
easeInExpo: easeInExpo,
easeOutExpo: easeOutExpo,
easeInOutExpo: easeInOutExpo,
easeInCirc: easeInCirc,
easeOutCirc: easeOutCirc,
easeInOutCirc: easeInOutCirc,
easeInElastic: easeInElastic,
easeOutElastic: easeOutElastic,
easeInOutElastic: easeInOutElastic,
easeInBack: easeInBack,
easeOutBack: easeOutBack,
easeInOutBack: easeInOutBack,
easeInBounce: easeInBounce,
easeOutBounce: easeOutBounce,
easeInOutBounce: easeInOutBounce
};
})();
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, capitalize = fabric.util.string.capitalize, clone = fabric.util.object.clone, toFixed = fabric.util.toFixed, parseUnit = fabric.util.parseUnit, multiplyTransformMatrices = fabric.util.multiplyTransformMatrices, reAllowedSVGTagNames = /^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/i, reViewBoxTagNames = /^(symbol|image|marker|pattern|view|svg)$/i, reNotAllowedAncestors = /^(?:pattern|defs|symbol|metadata)$/i, reAllowedParents = /^(symbol|g|a|svg)$/i, attributesMap = {
cx: "left",
x: "left",
r: "radius",
cy: "top",
y: "top",
display: "visible",
visibility: "visible",
transform: "transformMatrix",
"fill-opacity": "fillOpacity",
"fill-rule": "fillRule",
"font-family": "fontFamily",
"font-size": "fontSize",
"font-style": "fontStyle",
"font-weight": "fontWeight",
"stroke-dasharray": "strokeDashArray",
"stroke-linecap": "strokeLineCap",
"stroke-linejoin": "strokeLineJoin",
"stroke-miterlimit": "strokeMiterLimit",
"stroke-opacity": "strokeOpacity",
"stroke-width": "strokeWidth",
"text-decoration": "textDecoration",
"text-anchor": "originX"
}, colorAttributes = {
stroke: "strokeOpacity",
fill: "fillOpacity"
};
fabric.cssRules = {};
fabric.gradientDefs = {};
function normalizeAttr(attr) {
if (attr in attributesMap) {
return attributesMap[attr];
}
return attr;
}
function normalizeValue(attr, value, parentAttributes, fontSize) {
var isArray = Object.prototype.toString.call(value) === "[object Array]", parsed;
if ((attr === "fill" || attr === "stroke") && value === "none") {
value = "";
} else if (attr === "strokeDashArray") {
value = value.replace(/,/g, " ").split(/\s+/).map(function(n) {
return parseFloat(n);
});
} else if (attr === "transformMatrix") {
if (parentAttributes && parentAttributes.transformMatrix) {
value = multiplyTransformMatrices(parentAttributes.transformMatrix, fabric.parseTransformAttribute(value));
} else {
value = fabric.parseTransformAttribute(value);
}
} else if (attr === "visible") {
value = value === "none" || value === "hidden" ? false : true;
if (parentAttributes && parentAttributes.visible === false) {
value = false;
}
} else if (attr === "originX") {
value = value === "start" ? "left" : value === "end" ? "right" : "center";
} else {
parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize);
}
return !isArray && isNaN(parsed) ? value : parsed;
}
function _setStrokeFillOpacity(attributes) {
for (var attr in colorAttributes) {
if (typeof attributes[colorAttributes[attr]] === "undefined" || attributes[attr] === "") {
continue;
}
if (typeof attributes[attr] === "undefined") {
if (!fabric.Object.prototype[attr]) {
continue;
}
attributes[attr] = fabric.Object.prototype[attr];
}
if (attributes[attr].indexOf("url(") === 0) {
continue;
}
var color = new fabric.Color(attributes[attr]);
attributes[attr] = color.setAlpha(toFixed(color.getAlpha() * attributes[colorAttributes[attr]], 2)).toRgba();
}
return attributes;
}
function _getMultipleNodes(doc, nodeNames) {
var nodeName, nodeArray = [], nodeList;
for (var i = 0; i < nodeNames.length; i++) {
nodeName = nodeNames[i];
nodeList = doc.getElementsByTagName(nodeName);
nodeArray = nodeArray.concat(Array.prototype.slice.call(nodeList));
}
return nodeArray;
}
fabric.parseTransformAttribute = function() {
function rotateMatrix(matrix, args) {
var angle = args[0], x = args.length === 3 ? args[1] : 0, y = args.length === 3 ? args[2] : 0;
matrix[0] = Math.cos(angle);
matrix[1] = Math.sin(angle);
matrix[2] = -Math.sin(angle);
matrix[3] = Math.cos(angle);
matrix[4] = x - (matrix[0] * x + matrix[2] * y);
matrix[5] = y - (matrix[1] * x + matrix[3] * y);
}
function scaleMatrix(matrix, args) {
var multiplierX = args[0], multiplierY = args.length === 2 ? args[1] : args[0];
matrix[0] = multiplierX;
matrix[3] = multiplierY;
}
function skewXMatrix(matrix, args) {
matrix[2] = Math.tan(fabric.util.degreesToRadians(args[0]));
}
function skewYMatrix(matrix, args) {
matrix[1] = Math.tan(fabric.util.degreesToRadians(args[0]));
}
function translateMatrix(matrix, args) {
matrix[4] = args[0];
if (args.length === 2) {
matrix[5] = args[1];
}
}
var iMatrix = [ 1, 0, 0, 1, 0, 0 ], number = fabric.reNum, commaWsp = "(?:\\s+,?\\s*|,\\s*)", skewX = "(?:(skewX)\\s*\\(\\s*(" + number + ")\\s*\\))", skewY = "(?:(skewY)\\s*\\(\\s*(" + number + ")\\s*\\))", rotate = "(?:(rotate)\\s*\\(\\s*(" + number + ")(?:" + commaWsp + "(" + number + ")" + commaWsp + "(" + number + "))?\\s*\\))", scale = "(?:(scale)\\s*\\(\\s*(" + number + ")(?:" + commaWsp + "(" + number + "))?\\s*\\))", translate = "(?:(translate)\\s*\\(\\s*(" + number + ")(?:" + commaWsp + "(" + number + "))?\\s*\\))", matrix = "(?:(matrix)\\s*\\(\\s*" + "(" + number + ")" + commaWsp + "(" + number + ")" + commaWsp + "(" + number + ")" + commaWsp + "(" + number + ")" + commaWsp + "(" + number + ")" + commaWsp + "(" + number + ")" + "\\s*\\))", transform = "(?:" + matrix + "|" + translate + "|" + scale + "|" + rotate + "|" + skewX + "|" + skewY + ")", transforms = "(?:" + transform + "(?:" + commaWsp + "*" + transform + ")*" + ")", transformList = "^\\s*(?:" + transforms + "?)\\s*$", reTransformList = new RegExp(transformList), reTransform = new RegExp(transform, "g");
return function(attributeValue) {
var matrix = iMatrix.concat(), matrices = [];
if (!attributeValue || attributeValue && !reTransformList.test(attributeValue)) {
return matrix;
}
attributeValue.replace(reTransform, function(match) {
var m = new RegExp(transform).exec(match).filter(function(match) {
return !!match;
}), operation = m[1], args = m.slice(2).map(parseFloat);
switch (operation) {
case "translate":
translateMatrix(matrix, args);
break;
case "rotate":
args[0] = fabric.util.degreesToRadians(args[0]);
rotateMatrix(matrix, args);
break;
case "scale":
scaleMatrix(matrix, args);
break;
case "skewX":
skewXMatrix(matrix, args);
break;
case "skewY":
skewYMatrix(matrix, args);
break;
case "matrix":
matrix = args;
break;
}
matrices.push(matrix.concat());
matrix = iMatrix.concat();
});
var combinedMatrix = matrices[0];
while (matrices.length > 1) {
matrices.shift();
combinedMatrix = fabric.util.multiplyTransformMatrices(combinedMatrix, matrices[0]);
}
return combinedMatrix;
};
}();
function parseStyleString(style, oStyle) {
var attr, value;
style.replace(/;\s*$/, "").split(";").forEach(function(chunk) {
var pair = chunk.split(":");
attr = normalizeAttr(pair[0].trim().toLowerCase());
value = normalizeValue(attr, pair[1].trim());
oStyle[attr] = value;
});
}
function parseStyleObject(style, oStyle) {
var attr, value;
for (var prop in style) {
if (typeof style[prop] === "undefined") {
continue;
}
attr = normalizeAttr(prop.toLowerCase());
value = normalizeValue(attr, style[prop]);
oStyle[attr] = value;
}
}
function getGlobalStylesForElement(element, svgUid) {
var styles = {};
for (var rule in fabric.cssRules[svgUid]) {
if (elementMatchesRule(element, rule.split(" "))) {
for (var property in fabric.cssRules[svgUid][rule]) {
styles[property] = fabric.cssRules[svgUid][rule][property];
}
}
}
return styles;
}
function elementMatchesRule(element, selectors) {
var firstMatching, parentMatching = true;
firstMatching = selectorMatches(element, selectors.pop());
if (firstMatching && selectors.length) {
parentMatching = doesSomeParentMatch(element, selectors);
}
return firstMatching && parentMatching && selectors.length === 0;
}
function doesSomeParentMatch(element, selectors) {
var selector, parentMatching = true;
while (element.parentNode && element.parentNode.nodeType === 1 && selectors.length) {
if (parentMatching) {
selector = selectors.pop();
}
element = element.parentNode;
parentMatching = selectorMatches(element, selector);
}
return selectors.length === 0;
}
function selectorMatches(element, selector) {
var nodeName = element.nodeName, classNames = element.getAttribute("class"), id = element.getAttribute("id"), matcher;
matcher = new RegExp("^" + nodeName, "i");
selector = selector.replace(matcher, "");
if (id && selector.length) {
matcher = new RegExp("#" + id + "(?![a-zA-Z\\-]+)", "i");
selector = selector.replace(matcher, "");
}
if (classNames && selector.length) {
classNames = classNames.split(" ");
for (var i = classNames.length; i--; ) {
matcher = new RegExp("\\." + classNames[i] + "(?![a-zA-Z\\-]+)", "i");
selector = selector.replace(matcher, "");
}
}
return selector.length === 0;
}
function elementById(doc, id) {
var el;
doc.getElementById && (el = doc.getElementById(id));
if (el) {
return el;
}
var node, i, nodelist = doc.getElementsByTagName("*");
for (i = 0; i < nodelist.length; i++) {
node = nodelist[i];
if (id === node.getAttribute("id")) {
return node;
}
}
}
function parseUseDirectives(doc) {
var nodelist = _getMultipleNodes(doc, [ "use", "svg:use" ]), i = 0;
while (nodelist.length && i < nodelist.length) {
var el = nodelist[i], xlink = el.getAttribute("xlink:href").substr(1), x = el.getAttribute("x") || 0, y = el.getAttribute("y") || 0, el2 = elementById(doc, xlink).cloneNode(true), currentTrans = (el2.getAttribute("transform") || "") + " translate(" + x + ", " + y + ")", parentNode, oldLength = nodelist.length, attr, j, attrs, l;
applyViewboxTransform(el2);
if (/^svg$/i.test(el2.nodeName)) {
var el3 = el2.ownerDocument.createElement("g");
for (j = 0, attrs = el2.attributes, l = attrs.length; j < l; j++) {
attr = attrs.item(j);
el3.setAttribute(attr.nodeName, attr.nodeValue);
}
while (el2.firstChild) {
el3.appendChild(el2.firstChild);
}
el2 = el3;
}
for (j = 0, attrs = el.attributes, l = attrs.length; j < l; j++) {
attr = attrs.item(j);
if (attr.nodeName === "x" || attr.nodeName === "y" || attr.nodeName === "xlink:href") {
continue;
}
if (attr.nodeName === "transform") {
currentTrans = attr.nodeValue + " " + currentTrans;
} else {
el2.setAttribute(attr.nodeName, attr.nodeValue);
}
}
el2.setAttribute("transform", currentTrans);
el2.setAttribute("instantiated_by_use", "1");
el2.removeAttribute("id");
parentNode = el.parentNode;
parentNode.replaceChild(el2, el);
if (nodelist.length === oldLength) {
i++;
}
}
}
var reViewBoxAttrValue = new RegExp("^" + "\\s*(" + fabric.reNum + "+)\\s*,?" + "\\s*(" + fabric.reNum + "+)\\s*,?" + "\\s*(" + fabric.reNum + "+)\\s*,?" + "\\s*(" + fabric.reNum + "+)\\s*" + "$");
function applyViewboxTransform(element) {
var viewBoxAttr = element.getAttribute("viewBox"), scaleX = 1, scaleY = 1, minX = 0, minY = 0, viewBoxWidth, viewBoxHeight, matrix, el, widthAttr = element.getAttribute("width"), heightAttr = element.getAttribute("height"), x = element.getAttribute("x") || 0, y = element.getAttribute("y") || 0, preserveAspectRatio = element.getAttribute("preserveAspectRatio") || "", missingViewBox = !viewBoxAttr || !reViewBoxTagNames.test(element.nodeName) || !(viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue)), missingDimAttr = !widthAttr || !heightAttr || widthAttr === "100%" || heightAttr === "100%", toBeParsed = missingViewBox && missingDimAttr, parsedDim = {}, translateMatrix = "";
parsedDim.width = 0;
parsedDim.height = 0;
parsedDim.toBeParsed = toBeParsed;
if (toBeParsed) {
return parsedDim;
}
if (missingViewBox) {
parsedDim.width = parseUnit(widthAttr);
parsedDim.height = parseUnit(heightAttr);
return parsedDim;
}
minX = -parseFloat(viewBoxAttr[1]);
minY = -parseFloat(viewBoxAttr[2]);
viewBoxWidth = parseFloat(viewBoxAttr[3]);
viewBoxHeight = parseFloat(viewBoxAttr[4]);
if (!missingDimAttr) {
parsedDim.width = parseUnit(widthAttr);
parsedDim.height = parseUnit(heightAttr);
scaleX = parsedDim.width / viewBoxWidth;
scaleY = parsedDim.height / viewBoxHeight;
} else {
parsedDim.width = viewBoxWidth;
parsedDim.height = viewBoxHeight;
}
preserveAspectRatio = fabric.util.parsePreserveAspectRatioAttribute(preserveAspectRatio);
if (preserveAspectRatio.alignX !== "none") {
scaleY = scaleX = scaleX > scaleY ? scaleY : scaleX;
}
if (scaleX === 1 && scaleY === 1 && minX === 0 && minY === 0 && x === 0 && y === 0) {
return parsedDim;
}
if (x || y) {
translateMatrix = " translate(" + parseUnit(x) + " " + parseUnit(y) + ") ";
}
matrix = translateMatrix + " matrix(" + scaleX + " 0" + " 0 " + scaleY + " " + minX * scaleX + " " + minY * scaleY + ") ";
if (element.nodeName === "svg") {
el = element.ownerDocument.createElement("g");
while (element.firstChild) {
el.appendChild(element.firstChild);
}
element.appendChild(el);
} else {
el = element;
matrix = el.getAttribute("transform") + matrix;
}
el.setAttribute("transform", matrix);
return parsedDim;
}
fabric.parseSVGDocument = function() {
function hasAncestorWithNodeName(element, nodeName) {
while (element && (element = element.parentNode)) {
if (element.nodeName && nodeName.test(element.nodeName.replace("svg:", "")) && !element.getAttribute("instantiated_by_use")) {
return true;
}
}
return false;
}
return function(doc, callback, reviver) {
if (!doc) {
return;
}
parseUseDirectives(doc);
var startTime = new Date(), svgUid = fabric.Object.__uid++, options = applyViewboxTransform(doc), descendants = fabric.util.toArray(doc.getElementsByTagName("*"));
options.svgUid = svgUid;
if (descendants.length === 0 && fabric.isLikelyNode) {
descendants = doc.selectNodes('//*[name(.)!="svg"]');
var arr = [];
for (var i = 0, len = descendants.length; i < len; i++) {
arr[i] = descendants[i];
}
descendants = arr;
}
var elements = descendants.filter(function(el) {
applyViewboxTransform(el);
return reAllowedSVGTagNames.test(el.nodeName.replace("svg:", "")) && !hasAncestorWithNodeName(el, reNotAllowedAncestors);
});
if (!elements || elements && !elements.length) {
callback && callback([], {});
return;
}
fabric.gradientDefs[svgUid] = fabric.getGradientDefs(doc);
fabric.cssRules[svgUid] = fabric.getCSSRules(doc);
fabric.parseElements(elements, function(instances) {
fabric.documentParsingTime = new Date() - startTime;
if (callback) {
callback(instances, options);
}
}, clone(options), reviver);
};
}();
var svgCache = {
has: function(name, callback) {
callback(false);
},
get: function() {},
set: function() {}
};
function _enlivenCachedObject(cachedObject) {
var objects = cachedObject.objects, options = cachedObject.options;
objects = objects.map(function(o) {
return fabric[capitalize(o.type)].fromObject(o);
});
return {
objects: objects,
options: options
};
}
function _createSVGPattern(markup, canvas, property) {
if (canvas[property] && canvas[property].toSVG) {
markup.push('\t<pattern x="0" y="0" id="', property, 'Pattern" ', 'width="', canvas[property].source.width, '" height="', canvas[property].source.height, '" patternUnits="userSpaceOnUse">\n', '\t\t<image x="0" y="0" ', 'width="', canvas[property].source.width, '" height="', canvas[property].source.height, '" xlink:href="', canvas[property].source.src, '"></image>\n\t</pattern>\n');
}
}
var reFontDeclaration = new RegExp("(normal|italic)?\\s*(normal|small-caps)?\\s*" + "(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*(" + fabric.reNum + "(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|" + fabric.reNum + "))?\\s+(.*)");
extend(fabric, {
parseFontDeclaration: function(value, oStyle) {
var match = value.match(reFontDeclaration);
if (!match) {
return;
}
var fontStyle = match[1], fontWeight = match[3], fontSize = match[4], lineHeight = match[5], fontFamily = match[6];
if (fontStyle) {
oStyle.fontStyle = fontStyle;
}
if (fontWeight) {
oStyle.fontWeight = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight);
}
if (fontSize) {
oStyle.fontSize = parseUnit(fontSize);
}
if (fontFamily) {
oStyle.fontFamily = fontFamily;
}
if (lineHeight) {
oStyle.lineHeight = lineHeight === "normal" ? 1 : lineHeight;
}
},
getGradientDefs: function(doc) {
var tagArray = [ "linearGradient", "radialGradient", "svg:linearGradient", "svg:radialGradient" ], elList = _getMultipleNodes(doc, tagArray), el, j = 0, id, xlink, gradientDefs = {}, idsToXlinkMap = {};
j = elList.length;
while (j--) {
el = elList[j];
xlink = el.getAttribute("xlink:href");
id = el.getAttribute("id");
if (xlink) {
idsToXlinkMap[id] = xlink.substr(1);
}
gradientDefs[id] = el;
}
for (id in idsToXlinkMap) {
var el2 = gradientDefs[idsToXlinkMap[id]].cloneNode(true);
el = gradientDefs[id];
while (el2.firstChild) {
el.appendChild(el2.firstChild);
}
}
return gradientDefs;
},
parseAttributes: function(element, attributes, svgUid) {
if (!element) {
return;
}
var value, parentAttributes = {}, fontSize;
if (typeof svgUid === "undefined") {
svgUid = element.getAttribute("svgUid");
}
if (element.parentNode && reAllowedParents.test(element.parentNode.nodeName)) {
parentAttributes = fabric.parseAttributes(element.parentNode, attributes, svgUid);
}
fontSize = parentAttributes && parentAttributes.fontSize || element.getAttribute("font-size") || fabric.Text.DEFAULT_SVG_FONT_SIZE;
var ownAttributes = attributes.reduce(function(memo, attr) {
value = element.getAttribute(attr);
if (value) {
attr = normalizeAttr(attr);
value = normalizeValue(attr, value, parentAttributes, fontSize);
memo[attr] = value;
}
return memo;
}, {});
ownAttributes = extend(ownAttributes, extend(getGlobalStylesForElement(element, svgUid), fabric.parseStyleAttribute(element)));
if (ownAttributes.font) {
fabric.parseFontDeclaration(ownAttributes.font, ownAttributes);
}
return _setStrokeFillOpacity(extend(parentAttributes, ownAttributes));
},
parseElements: function(elements, callback, options, reviver) {
new fabric.ElementsParser(elements, callback, options, reviver).parse();
},
parseStyleAttribute: function(element) {
var oStyle = {}, style = element.getAttribute("style");
if (!style) {
return oStyle;
}
if (typeof style === "string") {
parseStyleString(style, oStyle);
} else {
parseStyleObject(style, oStyle);
}
return oStyle;
},
parsePointsAttribute: function(points) {
if (!points) {
return null;
}
points = points.replace(/,/g, " ").trim();
points = points.split(/\s+/);
var parsedPoints = [], i, len;
i = 0;
len = points.length;
for (;i < len; i += 2) {
parsedPoints.push({
x: parseFloat(points[i]),
y: parseFloat(points[i + 1])
});
}
return parsedPoints;
},
getCSSRules: function(doc) {
var styles = doc.getElementsByTagName("style"), allRules = {}, rules;
for (var i = 0, len = styles.length; i < len; i++) {
var styleContents = styles[i].textContent || styles[i].text;
styleContents = styleContents.replace(/\/\*[\s\S]*?\*\//g, "");
if (styleContents.trim() === "") {
continue;
}
rules = styleContents.match(/[^{]*\{[\s\S]*?\}/g);
rules = rules.map(function(rule) {
return rule.trim();
});
rules.forEach(function(rule) {
var match = rule.match(/([\s\S]*?)\s*\{([^}]*)\}/), ruleObj = {}, declaration = match[2].trim(), propertyValuePairs = declaration.replace(/;$/, "").split(/\s*;\s*/);
for (var i = 0, len = propertyValuePairs.length; i < len; i++) {
var pair = propertyValuePairs[i].split(/\s*:\s*/), property = normalizeAttr(pair[0]), value = normalizeValue(property, pair[1], pair[0]);
ruleObj[property] = value;
}
rule = match[1];
rule.split(",").forEach(function(_rule) {
_rule = _rule.replace(/^svg/i, "").trim();
if (_rule === "") {
return;
}
if (allRules[_rule]) {
fabric.util.object.extend(allRules[_rule], ruleObj);
} else {
allRules[_rule] = fabric.util.object.clone(ruleObj);
}
});
});
}
return allRules;
},
loadSVGFromURL: function(url, callback, reviver) {
url = url.replace(/^\n\s*/, "").trim();
svgCache.has(url, function(hasUrl) {
if (hasUrl) {
svgCache.get(url, function(value) {
var enlivedRecord = _enlivenCachedObject(value);
callback(enlivedRecord.objects, enlivedRecord.options);
});
} else {
new fabric.util.request(url, {
method: "get",
onComplete: onComplete
});
}
});
function onComplete(r) {
var xml = r.responseXML;
if (xml && !xml.documentElement && fabric.window.ActiveXObject && r.responseText) {
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = "false";
xml.loadXML(r.responseText.replace(/<!DOCTYPE[\s\S]*?(\[[\s\S]*\])*?>/i, ""));
}
if (!xml || !xml.documentElement) {
callback && callback(null);
}
fabric.parseSVGDocument(xml.documentElement, function(results, options) {
svgCache.set(url, {
objects: fabric.util.array.invoke(results, "toObject"),
options: options
});
callback && callback(results, options);
}, reviver);
}
},
loadSVGFromString: function(string, callback, reviver) {
string = string.trim();
var doc;
if (typeof DOMParser !== "undefined") {
var parser = new DOMParser();
if (parser && parser.parseFromString) {
doc = parser.parseFromString(string, "text/xml");
}
} else if (fabric.window.ActiveXObject) {
doc = new ActiveXObject("Microsoft.XMLDOM");
doc.async = "false";
doc.loadXML(string.replace(/<!DOCTYPE[\s\S]*?(\[[\s\S]*\])*?>/i, ""));
}
fabric.parseSVGDocument(doc.documentElement, function(results, options) {
callback(results, options);
}, reviver);
},
createSVGFontFacesMarkup: function(objects) {
var markup = "", fontList = {}, obj, fontFamily, style, row, rowIndex, _char, charIndex, fontPaths = fabric.fontPaths;
for (var i = 0, len = objects.length; i < len; i++) {
obj = objects[i];
fontFamily = obj.fontFamily;
if (obj.type.indexOf("text") === -1 || fontList[fontFamily] || !fontPaths[fontFamily]) {
continue;
}
fontList[fontFamily] = true;
if (!obj.styles) {
continue;
}
style = obj.styles;
for (rowIndex in style) {
row = style[rowIndex];
for (charIndex in row) {
_char = row[charIndex];
fontFamily = _char.fontFamily;
if (!fontList[fontFamily] && fontPaths[fontFamily]) {
fontList[fontFamily] = true;
}
}
}
}
for (var j in fontList) {
markup += [ "\t\t@font-face {\n", "\t\t\tfont-family: '", j, "';\n", "\t\t\tsrc: url('", fontPaths[j], "');\n", "\t\t}\n" ].join("");
}
if (markup) {
markup = [ '\t<style type="text/css">', "<![CDATA[\n", markup, "]]>", "</style>\n" ].join("");
}
return markup;
},
createSVGRefElementsMarkup: function(canvas) {
var markup = [];
_createSVGPattern(markup, canvas, "backgroundColor");
_createSVGPattern(markup, canvas, "overlayColor");
return markup.join("");
}
});
})( true ? exports : this);
fabric.ElementsParser = function(elements, callback, options, reviver) {
this.elements = elements;
this.callback = callback;
this.options = options;
this.reviver = reviver;
this.svgUid = options && options.svgUid || 0;
};
fabric.ElementsParser.prototype.parse = function() {
this.instances = new Array(this.elements.length);
this.numElements = this.elements.length;
this.createObjects();
};
fabric.ElementsParser.prototype.createObjects = function() {
for (var i = 0, len = this.elements.length; i < len; i++) {
this.elements[i].setAttribute("svgUid", this.svgUid);
(function(_obj, i) {
setTimeout(function() {
_obj.createObject(_obj.elements[i], i);
}, 0);
})(this, i);
}
};
fabric.ElementsParser.prototype.createObject = function(el, index) {
var klass = fabric[fabric.util.string.capitalize(el.tagName.replace("svg:", ""))];
if (klass && klass.fromElement) {
try {
this._createObject(klass, el, index);
} catch (err) {
fabric.log(err);
}
} else {
this.checkIfDone();
}
};
fabric.ElementsParser.prototype._createObject = function(klass, el, index) {
if (klass.async) {
klass.fromElement(el, this.createCallback(index, el), this.options);
} else {
var obj = klass.fromElement(el, this.options);
this.resolveGradient(obj, "fill");
this.resolveGradient(obj, "stroke");
this.reviver && this.reviver(el, obj);
this.instances[index] = obj;
this.checkIfDone();
}
};
fabric.ElementsParser.prototype.createCallback = function(index, el) {
var _this = this;
return function(obj) {
_this.resolveGradient(obj, "fill");
_this.resolveGradient(obj, "stroke");
_this.reviver && _this.reviver(el, obj);
_this.instances[index] = obj;
_this.checkIfDone();
};
};
fabric.ElementsParser.prototype.resolveGradient = function(obj, property) {
var instanceFillValue = obj.get(property);
if (!/^url\(/.test(instanceFillValue)) {
return;
}
var gradientId = instanceFillValue.slice(5, instanceFillValue.length - 1);
if (fabric.gradientDefs[this.svgUid][gradientId]) {
obj.set(property, fabric.Gradient.fromElement(fabric.gradientDefs[this.svgUid][gradientId], obj));
}
};
fabric.ElementsParser.prototype.checkIfDone = function() {
if (--this.numElements === 0) {
this.instances = this.instances.filter(function(el) {
return el != null;
});
this.callback(this.instances);
}
};
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {});
if (fabric.Point) {
fabric.warn("fabric.Point is already defined");
return;
}
fabric.Point = Point;
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype = {
type: "point",
constructor: Point,
add: function(that) {
return new Point(this.x + that.x, this.y + that.y);
},
addEquals: function(that) {
this.x += that.x;
this.y += that.y;
return this;
},
scalarAdd: function(scalar) {
return new Point(this.x + scalar, this.y + scalar);
},
scalarAddEquals: function(scalar) {
this.x += scalar;
this.y += scalar;
return this;
},
subtract: function(that) {
return new Point(this.x - that.x, this.y - that.y);
},
subtractEquals: function(that) {
this.x -= that.x;
this.y -= that.y;
return this;
},
scalarSubtract: function(scalar) {
return new Point(this.x - scalar, this.y - scalar);
},
scalarSubtractEquals: function(scalar) {
this.x -= scalar;
this.y -= scalar;
return this;
},
multiply: function(scalar) {
return new Point(this.x * scalar, this.y * scalar);
},
multiplyEquals: function(scalar) {
this.x *= scalar;
this.y *= scalar;
return this;
},
divide: function(scalar) {
return new Point(this.x / scalar, this.y / scalar);
},
divideEquals: function(scalar) {
this.x /= scalar;
this.y /= scalar;
return this;
},
eq: function(that) {
return this.x === that.x && this.y === that.y;
},
lt: function(that) {
return this.x < that.x && this.y < that.y;
},
lte: function(that) {
return this.x <= that.x && this.y <= that.y;
},
gt: function(that) {
return this.x > that.x && this.y > that.y;
},
gte: function(that) {
return this.x >= that.x && this.y >= that.y;
},
lerp: function(that, t) {
if (typeof t === "undefined") {
t = .5;
}
t = Math.max(Math.min(1, t), 0);
return new Point(this.x + (that.x - this.x) * t, this.y + (that.y - this.y) * t);
},
distanceFrom: function(that) {
var dx = this.x - that.x, dy = this.y - that.y;
return Math.sqrt(dx * dx + dy * dy);
},
midPointFrom: function(that) {
return this.lerp(that);
},
min: function(that) {
return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y));
},
max: function(that) {
return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y));
},
toString: function() {
return this.x + "," + this.y;
},
setXY: function(x, y) {
this.x = x;
this.y = y;
return this;
},
setX: function(x) {
this.x = x;
return this;
},
setY: function(y) {
this.y = y;
return this;
},
setFromPoint: function(that) {
this.x = that.x;
this.y = that.y;
return this;
},
swap: function(that) {
var x = this.x, y = this.y;
this.x = that.x;
this.y = that.y;
that.x = x;
that.y = y;
},
clone: function() {
return new Point(this.x, this.y);
}
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {});
if (fabric.Intersection) {
fabric.warn("fabric.Intersection is already defined");
return;
}
function Intersection(status) {
this.status = status;
this.points = [];
}
fabric.Intersection = Intersection;
fabric.Intersection.prototype = {
constructor: Intersection,
appendPoint: function(point) {
this.points.push(point);
return this;
},
appendPoints: function(points) {
this.points = this.points.concat(points);
return this;
}
};
fabric.Intersection.intersectLineLine = function(a1, a2, b1, b2) {
var result, uaT = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x), ubT = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x), uB = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);
if (uB !== 0) {
var ua = uaT / uB, ub = ubT / uB;
if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {
result = new Intersection("Intersection");
result.appendPoint(new fabric.Point(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y)));
} else {
result = new Intersection();
}
} else {
if (uaT === 0 || ubT === 0) {
result = new Intersection("Coincident");
} else {
result = new Intersection("Parallel");
}
}
return result;
};
fabric.Intersection.intersectLinePolygon = function(a1, a2, points) {
var result = new Intersection(), length = points.length, b1, b2, inter;
for (var i = 0; i < length; i++) {
b1 = points[i];
b2 = points[(i + 1) % length];
inter = Intersection.intersectLineLine(a1, a2, b1, b2);
result.appendPoints(inter.points);
}
if (result.points.length > 0) {
result.status = "Intersection";
}
return result;
};
fabric.Intersection.intersectPolygonPolygon = function(points1, points2) {
var result = new Intersection(), length = points1.length;
for (var i = 0; i < length; i++) {
var a1 = points1[i], a2 = points1[(i + 1) % length], inter = Intersection.intersectLinePolygon(a1, a2, points2);
result.appendPoints(inter.points);
}
if (result.points.length > 0) {
result.status = "Intersection";
}
return result;
};
fabric.Intersection.intersectPolygonRectangle = function(points, r1, r2) {
var min = r1.min(r2), max = r1.max(r2), topRight = new fabric.Point(max.x, min.y), bottomLeft = new fabric.Point(min.x, max.y), inter1 = Intersection.intersectLinePolygon(min, topRight, points), inter2 = Intersection.intersectLinePolygon(topRight, max, points), inter3 = Intersection.intersectLinePolygon(max, bottomLeft, points), inter4 = Intersection.intersectLinePolygon(bottomLeft, min, points), result = new Intersection();
result.appendPoints(inter1.points);
result.appendPoints(inter2.points);
result.appendPoints(inter3.points);
result.appendPoints(inter4.points);
if (result.points.length > 0) {
result.status = "Intersection";
}
return result;
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {});
if (fabric.Color) {
fabric.warn("fabric.Color is already defined.");
return;
}
function Color(color) {
if (!color) {
this.setSource([ 0, 0, 0, 1 ]);
} else {
this._tryParsingColor(color);
}
}
fabric.Color = Color;
fabric.Color.prototype = {
_tryParsingColor: function(color) {
var source;
if (color in Color.colorNameMap) {
color = Color.colorNameMap[color];
}
if (color === "transparent") {
source = [ 255, 255, 255, 0 ];
}
if (!source) {
source = Color.sourceFromHex(color);
}
if (!source) {
source = Color.sourceFromRgb(color);
}
if (!source) {
source = Color.sourceFromHsl(color);
}
if (!source) {
source = [ 0, 0, 0, 1 ];
}
if (source) {
this.setSource(source);
}
},
_rgbToHsl: function(r, g, b) {
r /= 255;
g /= 255;
b /= 255;
var h, s, l, max = fabric.util.array.max([ r, g, b ]), min = fabric.util.array.min([ r, g, b ]);
l = (max + min) / 2;
if (max === min) {
h = s = 0;
} else {
var d = max - min;
s = l > .5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return [ Math.round(h * 360), Math.round(s * 100), Math.round(l * 100) ];
},
getSource: function() {
return this._source;
},
setSource: function(source) {
this._source = source;
},
toRgb: function() {
var source = this.getSource();
return "rgb(" + source[0] + "," + source[1] + "," + source[2] + ")";
},
toRgba: function() {
var source = this.getSource();
return "rgba(" + source[0] + "," + source[1] + "," + source[2] + "," + source[3] + ")";
},
toHsl: function() {
var source = this.getSource(), hsl = this._rgbToHsl(source[0], source[1], source[2]);
return "hsl(" + hsl[0] + "," + hsl[1] + "%," + hsl[2] + "%)";
},
toHsla: function() {
var source = this.getSource(), hsl = this._rgbToHsl(source[0], source[1], source[2]);
return "hsla(" + hsl[0] + "," + hsl[1] + "%," + hsl[2] + "%," + source[3] + ")";
},
toHex: function() {
var source = this.getSource(), r, g, b;
r = source[0].toString(16);
r = r.length === 1 ? "0" + r : r;
g = source[1].toString(16);
g = g.length === 1 ? "0" + g : g;
b = source[2].toString(16);
b = b.length === 1 ? "0" + b : b;
return r.toUpperCase() + g.toUpperCase() + b.toUpperCase();
},
getAlpha: function() {
return this.getSource()[3];
},
setAlpha: function(alpha) {
var source = this.getSource();
source[3] = alpha;
this.setSource(source);
return this;
},
toGrayscale: function() {
var source = this.getSource(), average = parseInt((source[0] * .3 + source[1] * .59 + source[2] * .11).toFixed(0), 10), currentAlpha = source[3];
this.setSource([ average, average, average, currentAlpha ]);
return this;
},
toBlackWhite: function(threshold) {
var source = this.getSource(), average = (source[0] * .3 + source[1] * .59 + source[2] * .11).toFixed(0), currentAlpha = source[3];
threshold = threshold || 127;
average = Number(average) < Number(threshold) ? 0 : 255;
this.setSource([ average, average, average, currentAlpha ]);
return this;
},
overlayWith: function(otherColor) {
if (!(otherColor instanceof Color)) {
otherColor = new Color(otherColor);
}
var result = [], alpha = this.getAlpha(), otherAlpha = .5, source = this.getSource(), otherSource = otherColor.getSource();
for (var i = 0; i < 3; i++) {
result.push(Math.round(source[i] * (1 - otherAlpha) + otherSource[i] * otherAlpha));
}
result[3] = alpha;
this.setSource(result);
return this;
}
};
fabric.Color.reRGBa = /^rgba?\(\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/;
fabric.Color.reHSLa = /^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3}\%)\s*,\s*(\d{1,3}\%)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/;
fabric.Color.reHex = /^#?([0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{4}|[0-9a-f]{3})$/i;
fabric.Color.colorNameMap = {
aqua: "#00FFFF",
black: "#000000",
blue: "#0000FF",
fuchsia: "#FF00FF",
gray: "#808080",
grey: "#808080",
green: "#008000",
lime: "#00FF00",
maroon: "#800000",
navy: "#000080",
olive: "#808000",
orange: "#FFA500",
purple: "#800080",
red: "#FF0000",
silver: "#C0C0C0",
teal: "#008080",
white: "#FFFFFF",
yellow: "#FFFF00"
};
function hue2rgb(p, q, t) {
if (t < 0) {
t += 1;
}
if (t > 1) {
t -= 1;
}
if (t < 1 / 6) {
return p + (q - p) * 6 * t;
}
if (t < 1 / 2) {
return q;
}
if (t < 2 / 3) {
return p + (q - p) * (2 / 3 - t) * 6;
}
return p;
}
fabric.Color.fromRgb = function(color) {
return Color.fromSource(Color.sourceFromRgb(color));
};
fabric.Color.sourceFromRgb = function(color) {
var match = color.match(Color.reRGBa);
if (match) {
var r = parseInt(match[1], 10) / (/%$/.test(match[1]) ? 100 : 1) * (/%$/.test(match[1]) ? 255 : 1), g = parseInt(match[2], 10) / (/%$/.test(match[2]) ? 100 : 1) * (/%$/.test(match[2]) ? 255 : 1), b = parseInt(match[3], 10) / (/%$/.test(match[3]) ? 100 : 1) * (/%$/.test(match[3]) ? 255 : 1);
return [ parseInt(r, 10), parseInt(g, 10), parseInt(b, 10), match[4] ? parseFloat(match[4]) : 1 ];
}
};
fabric.Color.fromRgba = Color.fromRgb;
fabric.Color.fromHsl = function(color) {
return Color.fromSource(Color.sourceFromHsl(color));
};
fabric.Color.sourceFromHsl = function(color) {
var match = color.match(Color.reHSLa);
if (!match) {
return;
}
var h = (parseFloat(match[1]) % 360 + 360) % 360 / 360, s = parseFloat(match[2]) / (/%$/.test(match[2]) ? 100 : 1), l = parseFloat(match[3]) / (/%$/.test(match[3]) ? 100 : 1), r, g, b;
if (s === 0) {
r = g = b = l;
} else {
var q = l <= .5 ? l * (s + 1) : l + s - l * s, p = l * 2 - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return [ Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), match[4] ? parseFloat(match[4]) : 1 ];
};
fabric.Color.fromHsla = Color.fromHsl;
fabric.Color.fromHex = function(color) {
return Color.fromSource(Color.sourceFromHex(color));
};
fabric.Color.sourceFromHex = function(color) {
if (color.match(Color.reHex)) {
var value = color.slice(color.indexOf("#") + 1), isShortNotation = value.length === 3 || value.length === 4, isRGBa = value.length === 8 || value.length === 4, r = isShortNotation ? value.charAt(0) + value.charAt(0) : value.substring(0, 2), g = isShortNotation ? value.charAt(1) + value.charAt(1) : value.substring(2, 4), b = isShortNotation ? value.charAt(2) + value.charAt(2) : value.substring(4, 6), a = isRGBa ? isShortNotation ? value.charAt(3) + value.charAt(3) : value.substring(6, 8) : "FF";
return [ parseInt(r, 16), parseInt(g, 16), parseInt(b, 16), parseFloat((parseInt(a, 16) / 255).toFixed(2)) ];
}
};
fabric.Color.fromSource = function(source) {
var oColor = new Color();
oColor.setSource(source);
return oColor;
};
})( true ? exports : this);
(function() {
function getColorStop(el) {
var style = el.getAttribute("style"), offset = el.getAttribute("offset") || 0, color, colorAlpha, opacity;
offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);
offset = offset < 0 ? 0 : offset > 1 ? 1 : offset;
if (style) {
var keyValuePairs = style.split(/\s*;\s*/);
if (keyValuePairs[keyValuePairs.length - 1] === "") {
keyValuePairs.pop();
}
for (var i = keyValuePairs.length; i--; ) {
var split = keyValuePairs[i].split(/\s*:\s*/), key = split[0].trim(), value = split[1].trim();
if (key === "stop-color") {
color = value;
} else if (key === "stop-opacity") {
opacity = value;
}
}
}
if (!color) {
color = el.getAttribute("stop-color") || "rgb(0,0,0)";
}
if (!opacity) {
opacity = el.getAttribute("stop-opacity");
}
color = new fabric.Color(color);
colorAlpha = color.getAlpha();
opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity);
opacity *= colorAlpha;
return {
offset: offset,
color: color.toRgb(),
opacity: opacity
};
}
function getLinearCoords(el) {
return {
x1: el.getAttribute("x1") || 0,
y1: el.getAttribute("y1") || 0,
x2: el.getAttribute("x2") || "100%",
y2: el.getAttribute("y2") || 0
};
}
function getRadialCoords(el) {
return {
x1: el.getAttribute("fx") || el.getAttribute("cx") || "50%",
y1: el.getAttribute("fy") || el.getAttribute("cy") || "50%",
r1: 0,
x2: el.getAttribute("cx") || "50%",
y2: el.getAttribute("cy") || "50%",
r2: el.getAttribute("r") || "50%"
};
}
fabric.Gradient = fabric.util.createClass({
offsetX: 0,
offsetY: 0,
initialize: function(options) {
options || (options = {});
var coords = {};
this.id = fabric.Object.__uid++;
this.type = options.type || "linear";
coords = {
x1: options.coords.x1 || 0,
y1: options.coords.y1 || 0,
x2: options.coords.x2 || 0,
y2: options.coords.y2 || 0
};
if (this.type === "radial") {
coords.r1 = options.coords.r1 || 0;
coords.r2 = options.coords.r2 || 0;
}
this.coords = coords;
this.colorStops = options.colorStops.slice();
if (options.gradientTransform) {
this.gradientTransform = options.gradientTransform;
}
this.offsetX = options.offsetX || this.offsetX;
this.offsetY = options.offsetY || this.offsetY;
},
addColorStop: function(colorStop) {
for (var position in colorStop) {
var color = new fabric.Color(colorStop[position]);
this.colorStops.push({
offset: position,
color: color.toRgb(),
opacity: color.getAlpha()
});
}
return this;
},
toObject: function() {
return {
type: this.type,
coords: this.coords,
colorStops: this.colorStops,
offsetX: this.offsetX,
offsetY: this.offsetY,
gradientTransform: this.gradientTransform ? this.gradientTransform.concat() : this.gradientTransform
};
},
toSVG: function(object) {
var coords = fabric.util.object.clone(this.coords), markup, commonAttributes;
this.colorStops.sort(function(a, b) {
return a.offset - b.offset;
});
if (!(object.group && object.group.type === "path-group")) {
for (var prop in coords) {
if (prop === "x1" || prop === "x2" || prop === "r2") {
coords[prop] += this.offsetX - object.width / 2;
} else if (prop === "y1" || prop === "y2") {
coords[prop] += this.offsetY - object.height / 2;
}
}
}
commonAttributes = 'id="SVGID_' + this.id + '" gradientUnits="userSpaceOnUse"';
if (this.gradientTransform) {
commonAttributes += ' gradientTransform="matrix(' + this.gradientTransform.join(" ") + ')" ';
}
if (this.type === "linear") {
markup = [ "<linearGradient ", commonAttributes, ' x1="', coords.x1, '" y1="', coords.y1, '" x2="', coords.x2, '" y2="', coords.y2, '">\n' ];
} else if (this.type === "radial") {
markup = [ "<radialGradient ", commonAttributes, ' cx="', coords.x2, '" cy="', coords.y2, '" r="', coords.r2, '" fx="', coords.x1, '" fy="', coords.y1, '">\n' ];
}
for (var i = 0; i < this.colorStops.length; i++) {
markup.push("<stop ", 'offset="', this.colorStops[i].offset * 100 + "%", '" style="stop-color:', this.colorStops[i].color, this.colorStops[i].opacity !== null ? ";stop-opacity: " + this.colorStops[i].opacity : ";", '"/>\n');
}
markup.push(this.type === "linear" ? "</linearGradient>\n" : "</radialGradient>\n");
return markup.join("");
},
toLive: function(ctx, object) {
var gradient, prop, coords = fabric.util.object.clone(this.coords);
if (!this.type) {
return;
}
if (object.group && object.group.type === "path-group") {
for (prop in coords) {
if (prop === "x1" || prop === "x2") {
coords[prop] += -this.offsetX + object.width / 2;
} else if (prop === "y1" || prop === "y2") {
coords[prop] += -this.offsetY + object.height / 2;
}
}
}
if (this.type === "linear") {
gradient = ctx.createLinearGradient(coords.x1, coords.y1, coords.x2, coords.y2);
} else if (this.type === "radial") {
gradient = ctx.createRadialGradient(coords.x1, coords.y1, coords.r1, coords.x2, coords.y2, coords.r2);
}
for (var i = 0, len = this.colorStops.length; i < len; i++) {
var color = this.colorStops[i].color, opacity = this.colorStops[i].opacity, offset = this.colorStops[i].offset;
if (typeof opacity !== "undefined") {
color = new fabric.Color(color).setAlpha(opacity).toRgba();
}
gradient.addColorStop(parseFloat(offset), color);
}
return gradient;
}
});
fabric.util.object.extend(fabric.Gradient, {
fromElement: function(el, instance) {
var colorStopEls = el.getElementsByTagName("stop"), type, gradientUnits = el.getAttribute("gradientUnits") || "objectBoundingBox", gradientTransform = el.getAttribute("gradientTransform"), colorStops = [], coords, ellipseMatrix;
if (el.nodeName === "linearGradient" || el.nodeName === "LINEARGRADIENT") {
type = "linear";
} else {
type = "radial";
}
if (type === "linear") {
coords = getLinearCoords(el);
} else if (type === "radial") {
coords = getRadialCoords(el);
}
for (var i = colorStopEls.length; i--; ) {
colorStops.push(getColorStop(colorStopEls[i]));
}
ellipseMatrix = _convertPercentUnitsToValues(instance, coords, gradientUnits);
var gradient = new fabric.Gradient({
type: type,
coords: coords,
colorStops: colorStops,
offsetX: -instance.left,
offsetY: -instance.top
});
if (gradientTransform || ellipseMatrix !== "") {
gradient.gradientTransform = fabric.parseTransformAttribute((gradientTransform || "") + ellipseMatrix);
}
return gradient;
},
forObject: function(obj, options) {
options || (options = {});
_convertPercentUnitsToValues(obj, options.coords, "userSpaceOnUse");
return new fabric.Gradient(options);
}
});
function _convertPercentUnitsToValues(object, options, gradientUnits) {
var propValue, addFactor = 0, multFactor = 1, ellipseMatrix = "";
for (var prop in options) {
if (options[prop] === "Infinity") {
options[prop] = 1;
} else if (options[prop] === "-Infinity") {
options[prop] = 0;
}
propValue = parseFloat(options[prop], 10);
if (typeof options[prop] === "string" && /^\d+%$/.test(options[prop])) {
multFactor = .01;
} else {
multFactor = 1;
}
if (prop === "x1" || prop === "x2" || prop === "r2") {
multFactor *= gradientUnits === "objectBoundingBox" ? object.width : 1;
addFactor = gradientUnits === "objectBoundingBox" ? object.left || 0 : 0;
} else if (prop === "y1" || prop === "y2") {
multFactor *= gradientUnits === "objectBoundingBox" ? object.height : 1;
addFactor = gradientUnits === "objectBoundingBox" ? object.top || 0 : 0;
}
options[prop] = propValue * multFactor + addFactor;
}
if (object.type === "ellipse" && options.r2 !== null && gradientUnits === "objectBoundingBox" && object.rx !== object.ry) {
var scaleFactor = object.ry / object.rx;
ellipseMatrix = " scale(1, " + scaleFactor + ")";
if (options.y1) {
options.y1 /= scaleFactor;
}
if (options.y2) {
options.y2 /= scaleFactor;
}
}
return ellipseMatrix;
}
})();
fabric.Pattern = fabric.util.createClass({
repeat: "repeat",
offsetX: 0,
offsetY: 0,
initialize: function(options) {
options || (options = {});
this.id = fabric.Object.__uid++;
if (options.source) {
if (typeof options.source === "string") {
if (typeof fabric.util.getFunctionBody(options.source) !== "undefined") {
this.source = new Function(fabric.util.getFunctionBody(options.source));
} else {
var _this = this;
this.source = fabric.util.createImage();
fabric.util.loadImage(options.source, function(img) {
_this.source = img;
});
}
} else {
this.source = options.source;
}
}
if (options.repeat) {
this.repeat = options.repeat;
}
if (options.offsetX) {
this.offsetX = options.offsetX;
}
if (options.offsetY) {
this.offsetY = options.offsetY;
}
},
toObject: function() {
var source;
if (typeof this.source === "function") {
source = String(this.source);
} else if (typeof this.source.src === "string") {
source = this.source.src;
} else if (typeof this.source === "object" && this.source.toDataURL) {
source = this.source.toDataURL();
}
return {
source: source,
repeat: this.repeat,
offsetX: this.offsetX,
offsetY: this.offsetY
};
},
toSVG: function(object) {
var patternSource = typeof this.source === "function" ? this.source() : this.source, patternWidth = patternSource.width / object.getWidth(), patternHeight = patternSource.height / object.getHeight(), patternOffsetX = this.offsetX / object.getWidth(), patternOffsetY = this.offsetY / object.getHeight(), patternImgSrc = "";
if (this.repeat === "repeat-x" || this.repeat === "no-repeat") {
patternHeight = 1;
}
if (this.repeat === "repeat-y" || this.repeat === "no-repeat") {
patternWidth = 1;
}
if (patternSource.src) {
patternImgSrc = patternSource.src;
} else if (patternSource.toDataURL) {
patternImgSrc = patternSource.toDataURL();
}
return '<pattern id="SVGID_' + this.id + '" x="' + patternOffsetX + '" y="' + patternOffsetY + '" width="' + patternWidth + '" height="' + patternHeight + '">\n' + '<image x="0" y="0"' + ' width="' + patternSource.width + '" height="' + patternSource.height + '" xlink:href="' + patternImgSrc + '"></image>\n' + "</pattern>\n";
},
toLive: function(ctx) {
var source = typeof this.source === "function" ? this.source() : this.source;
if (!source) {
return "";
}
if (typeof source.src !== "undefined") {
if (!source.complete) {
return "";
}
if (source.naturalWidth === 0 || source.naturalHeight === 0) {
return "";
}
}
return ctx.createPattern(source, this.repeat);
}
});
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), toFixed = fabric.util.toFixed;
if (fabric.Shadow) {
fabric.warn("fabric.Shadow is already defined.");
return;
}
fabric.Shadow = fabric.util.createClass({
color: "rgb(0,0,0)",
blur: 0,
offsetX: 0,
offsetY: 0,
affectStroke: false,
includeDefaultValues: true,
initialize: function(options) {
if (typeof options === "string") {
options = this._parseShadow(options);
}
for (var prop in options) {
this[prop] = options[prop];
}
this.id = fabric.Object.__uid++;
},
_parseShadow: function(shadow) {
var shadowStr = shadow.trim(), offsetsAndBlur = fabric.Shadow.reOffsetsAndBlur.exec(shadowStr) || [], color = shadowStr.replace(fabric.Shadow.reOffsetsAndBlur, "") || "rgb(0,0,0)";
return {
color: color.trim(),
offsetX: parseInt(offsetsAndBlur[1], 10) || 0,
offsetY: parseInt(offsetsAndBlur[2], 10) || 0,
blur: parseInt(offsetsAndBlur[3], 10) || 0
};
},
toString: function() {
return [ this.offsetX, this.offsetY, this.blur, this.color ].join("px ");
},
toSVG: function(object) {
var fBoxX = 40, fBoxY = 40, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, offset = fabric.util.rotateVector({
x: this.offsetX,
y: this.offsetY
}, fabric.util.degreesToRadians(-object.angle)), BLUR_BOX = 20;
if (object.width && object.height) {
fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;
fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;
}
if (object.flipX) {
offset.x *= -1;
}
if (object.flipY) {
offset.y *= -1;
}
return '<filter id="SVGID_' + this.id + '" y="-' + fBoxY + '%" height="' + (100 + 2 * fBoxY) + '%" ' + 'x="-' + fBoxX + '%" width="' + (100 + 2 * fBoxX) + '%" ' + ">\n" + '\t<feGaussianBlur in="SourceAlpha" stdDeviation="' + toFixed(this.blur ? this.blur / 2 : 0, NUM_FRACTION_DIGITS) + '"></feGaussianBlur>\n' + '\t<feOffset dx="' + toFixed(offset.x, NUM_FRACTION_DIGITS) + '" dy="' + toFixed(offset.y, NUM_FRACTION_DIGITS) + '" result="oBlur" ></feOffset>\n' + '\t<feFlood flood-color="' + this.color + '"/>\n' + '\t<feComposite in2="oBlur" operator="in" />\n' + "\t<feMerge>\n" + "\t\t<feMergeNode></feMergeNode>\n" + '\t\t<feMergeNode in="SourceGraphic"></feMergeNode>\n' + "\t</feMerge>\n" + "</filter>\n";
},
toObject: function() {
if (this.includeDefaultValues) {
return {
color: this.color,
blur: this.blur,
offsetX: this.offsetX,
offsetY: this.offsetY,
affectStroke: this.affectStroke
};
}
var obj = {}, proto = fabric.Shadow.prototype;
[ "color", "blur", "offsetX", "offsetY", "affectStroke" ].forEach(function(prop) {
if (this[prop] !== proto[prop]) {
obj[prop] = this[prop];
}
}, this);
return obj;
}
});
fabric.Shadow.reOffsetsAndBlur = /(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/;
})( true ? exports : this);
(function() {
"use strict";
if (fabric.StaticCanvas) {
fabric.warn("fabric.StaticCanvas is already defined.");
return;
}
var extend = fabric.util.object.extend, getElementOffset = fabric.util.getElementOffset, removeFromArray = fabric.util.removeFromArray, toFixed = fabric.util.toFixed, CANVAS_INIT_ERROR = new Error("Could not initialize `canvas` element");
fabric.StaticCanvas = fabric.util.createClass({
initialize: function(el, options) {
options || (options = {});
this._initStatic(el, options);
},
backgroundColor: "",
backgroundImage: null,
overlayColor: "",
overlayImage: null,
includeDefaultValues: true,
stateful: true,
renderOnAddRemove: true,
clipTo: null,
controlsAboveOverlay: false,
allowTouchScrolling: false,
imageSmoothingEnabled: true,
viewportTransform: [ 1, 0, 0, 1, 0, 0 ],
backgroundVpt: true,
overlayVpt: true,
onBeforeScaleRotate: function() {},
enableRetinaScaling: true,
_initStatic: function(el, options) {
var cb = fabric.StaticCanvas.prototype.renderAll.bind(this);
this._objects = [];
this._createLowerCanvas(el);
this._initOptions(options);
this._setImageSmoothing();
if (!this.interactive) {
this._initRetinaScaling();
}
if (options.overlayImage) {
this.setOverlayImage(options.overlayImage, cb);
}
if (options.backgroundImage) {
this.setBackgroundImage(options.backgroundImage, cb);
}
if (options.backgroundColor) {
this.setBackgroundColor(options.backgroundColor, cb);
}
if (options.overlayColor) {
this.setOverlayColor(options.overlayColor, cb);
}
this.calcOffset();
},
_isRetinaScaling: function() {
return fabric.devicePixelRatio !== 1 && this.enableRetinaScaling;
},
getRetinaScaling: function() {
return this._isRetinaScaling() ? fabric.devicePixelRatio : 1;
},
_initRetinaScaling: function() {
if (!this._isRetinaScaling()) {
return;
}
this.lowerCanvasEl.setAttribute("width", this.width * fabric.devicePixelRatio);
this.lowerCanvasEl.setAttribute("height", this.height * fabric.devicePixelRatio);
this.contextContainer.scale(fabric.devicePixelRatio, fabric.devicePixelRatio);
},
calcOffset: function() {
this._offset = getElementOffset(this.lowerCanvasEl);
return this;
},
setOverlayImage: function(image, callback, options) {
return this.__setBgOverlayImage("overlayImage", image, callback, options);
},
setBackgroundImage: function(image, callback, options) {
return this.__setBgOverlayImage("backgroundImage", image, callback, options);
},
setOverlayColor: function(overlayColor, callback) {
return this.__setBgOverlayColor("overlayColor", overlayColor, callback);
},
setBackgroundColor: function(backgroundColor, callback) {
return this.__setBgOverlayColor("backgroundColor", backgroundColor, callback);
},
_setImageSmoothing: function() {
var ctx = this.getContext();
ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled || ctx.webkitImageSmoothingEnabled || ctx.mozImageSmoothingEnabled || ctx.msImageSmoothingEnabled || ctx.oImageSmoothingEnabled;
ctx.imageSmoothingEnabled = this.imageSmoothingEnabled;
},
__setBgOverlayImage: function(property, image, callback, options) {
if (typeof image === "string") {
fabric.util.loadImage(image, function(img) {
img && (this[property] = new fabric.Image(img, options));
callback && callback(img);
}, this, options && options.crossOrigin);
} else {
options && image.setOptions(options);
this[property] = image;
callback && callback(image);
}
return this;
},
__setBgOverlayColor: function(property, color, callback) {
if (color && color.source) {
var _this = this;
fabric.util.loadImage(color.source, function(img) {
_this[property] = new fabric.Pattern({
source: img,
repeat: color.repeat,
offsetX: color.offsetX,
offsetY: color.offsetY
});
callback && callback();
});
} else {
this[property] = color;
callback && callback();
}
return this;
},
_createCanvasElement: function(canvasEl) {
var element = fabric.util.createCanvasElement(canvasEl);
if (!element.style) {
element.style = {};
}
if (!element) {
throw CANVAS_INIT_ERROR;
}
if (typeof element.getContext === "undefined") {
throw CANVAS_INIT_ERROR;
}
return element;
},
_initOptions: function(options) {
for (var prop in options) {
this[prop] = options[prop];
}
this.width = this.width || parseInt(this.lowerCanvasEl.width, 10) || 0;
this.height = this.height || parseInt(this.lowerCanvasEl.height, 10) || 0;
if (!this.lowerCanvasEl.style) {
return;
}
this.lowerCanvasEl.width = this.width;
this.lowerCanvasEl.height = this.height;
this.lowerCanvasEl.style.width = this.width + "px";
this.lowerCanvasEl.style.height = this.height + "px";
this.viewportTransform = this.viewportTransform.slice();
},
_createLowerCanvas: function(canvasEl) {
this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement(canvasEl);
fabric.util.addClass(this.lowerCanvasEl, "lower-canvas");
if (this.interactive) {
this._applyCanvasStyle(this.lowerCanvasEl);
}
this.contextContainer = this.lowerCanvasEl.getContext("2d");
},
getWidth: function() {
return this.width;
},
getHeight: function() {
return this.height;
},
setWidth: function(value, options) {
return this.setDimensions({
width: value
}, options);
},
setHeight: function(value, options) {
return this.setDimensions({
height: value
}, options);
},
setDimensions: function(dimensions, options) {
var cssValue;
options = options || {};
for (var prop in dimensions) {
cssValue = dimensions[prop];
if (!options.cssOnly) {
this._setBackstoreDimension(prop, dimensions[prop]);
cssValue += "px";
}
if (!options.backstoreOnly) {
this._setCssDimension(prop, cssValue);
}
}
this._initRetinaScaling();
this._setImageSmoothing();
this.calcOffset();
if (!options.cssOnly) {
this.renderAll();
}
return this;
},
_setBackstoreDimension: function(prop, value) {
this.lowerCanvasEl[prop] = value;
if (this.upperCanvasEl) {
this.upperCanvasEl[prop] = value;
}
if (this.cacheCanvasEl) {
this.cacheCanvasEl[prop] = value;
}
this[prop] = value;
return this;
},
_setCssDimension: function(prop, value) {
this.lowerCanvasEl.style[prop] = value;
if (this.upperCanvasEl) {
this.upperCanvasEl.style[prop] = value;
}
if (this.wrapperEl) {
this.wrapperEl.style[prop] = value;
}
return this;
},
getZoom: function() {
return Math.sqrt(this.viewportTransform[0] * this.viewportTransform[3]);
},
setViewportTransform: function(vpt) {
var activeGroup = this._activeGroup, object;
this.viewportTransform = vpt;
for (var i = 0, len = this._objects.length; i < len; i++) {
object = this._objects[i];
object.group || object.setCoords();
}
if (activeGroup) {
activeGroup.setCoords();
}
this.renderAll();
return this;
},
zoomToPoint: function(point, value) {
var before = point, vpt = this.viewportTransform.slice(0);
point = fabric.util.transformPoint(point, fabric.util.invertTransform(this.viewportTransform));
vpt[0] = value;
vpt[3] = value;
var after = fabric.util.transformPoint(point, vpt);
vpt[4] += before.x - after.x;
vpt[5] += before.y - after.y;
return this.setViewportTransform(vpt);
},
setZoom: function(value) {
this.zoomToPoint(new fabric.Point(0, 0), value);
return this;
},
absolutePan: function(point) {
var vpt = this.viewportTransform.slice(0);
vpt[4] = -point.x;
vpt[5] = -point.y;
return this.setViewportTransform(vpt);
},
relativePan: function(point) {
return this.absolutePan(new fabric.Point(-point.x - this.viewportTransform[4], -point.y - this.viewportTransform[5]));
},
getElement: function() {
return this.lowerCanvasEl;
},
_onObjectAdded: function(obj) {
this.stateful && obj.setupState();
obj._set("canvas", this);
obj.setCoords();
this.fire("object:added", {
target: obj
});
obj.fire("added");
},
_onObjectRemoved: function(obj) {
this.fire("object:removed", {
target: obj
});
obj.fire("removed");
delete obj.canvas;
},
clearContext: function(ctx) {
ctx.clearRect(0, 0, this.width, this.height);
return this;
},
getContext: function() {
return this.contextContainer;
},
clear: function() {
this._objects.length = 0;
this.backgroundImage = null;
this.overlayImage = null;
this.backgroundColor = "";
this.overlayColor = "";
if (this._hasITextHandlers) {
this.off("selection:cleared", this._canvasITextSelectionClearedHanlder);
this.off("object:selected", this._canvasITextSelectionClearedHanlder);
this.off("mouse:up", this._mouseUpITextHandler);
this._iTextInstances = null;
this._hasITextHandlers = false;
}
this.clearContext(this.contextContainer);
this.fire("canvas:cleared");
this.renderAll();
return this;
},
renderAll: function() {
var canvasToDrawOn = this.contextContainer;
this.renderCanvas(canvasToDrawOn, this._objects);
return this;
},
renderCanvas: function(ctx, objects) {
this.clearContext(ctx);
this.fire("before:render");
if (this.clipTo) {
fabric.util.clipContext(this, ctx);
}
this._renderBackground(ctx);
ctx.save();
ctx.transform.apply(ctx, this.viewportTransform);
this._renderObjects(ctx, objects);
ctx.restore();
if (!this.controlsAboveOverlay && this.interactive) {
this.drawControls(ctx);
}
if (this.clipTo) {
ctx.restore();
}
this._renderOverlay(ctx);
if (this.controlsAboveOverlay && this.interactive) {
this.drawControls(ctx);
}
this.fire("after:render");
},
_renderObjects: function(ctx, objects) {
for (var i = 0, length = objects.length; i < length; ++i) {
objects[i] && objects[i].render(ctx);
}
},
_renderBackgroundOrOverlay: function(ctx, property) {
var object = this[property + "Color"];
if (object) {
ctx.fillStyle = object.toLive ? object.toLive(ctx) : object;
ctx.fillRect(object.offsetX || 0, object.offsetY || 0, this.width, this.height);
}
object = this[property + "Image"];
if (object) {
if (this[property + "Vpt"]) {
ctx.save();
ctx.transform.apply(ctx, this.viewportTransform);
}
object.render(ctx);
this[property + "Vpt"] && ctx.restore();
}
},
_renderBackground: function(ctx) {
this._renderBackgroundOrOverlay(ctx, "background");
},
_renderOverlay: function(ctx) {
this._renderBackgroundOrOverlay(ctx, "overlay");
},
getCenter: function() {
return {
top: this.getHeight() / 2,
left: this.getWidth() / 2
};
},
centerObjectH: function(object) {
return this._centerObject(object, new fabric.Point(this.getCenter().left, object.getCenterPoint().y));
},
centerObjectV: function(object) {
return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, this.getCenter().top));
},
centerObject: function(object) {
var center = this.getCenter();
return this._centerObject(object, new fabric.Point(center.left, center.top));
},
viewportCenterObject: function(object) {
var vpCenter = this.getVpCenter();
return this._centerObject(object, vpCenter);
},
viewportCenterObjectH: function(object) {
var vpCenter = this.getVpCenter();
this._centerObject(object, new fabric.Point(vpCenter.x, object.getCenterPoint().y));
return this;
},
viewportCenterObjectV: function(object) {
var vpCenter = this.getVpCenter();
return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, vpCenter.y));
},
getVpCenter: function() {
var center = this.getCenter(), iVpt = fabric.util.invertTransform(this.viewportTransform);
return fabric.util.transformPoint({
x: center.left,
y: center.top
}, iVpt);
},
_centerObject: function(object, center) {
object.setPositionByOrigin(center, "center", "center");
this.renderAll();
return this;
},
toDatalessJSON: function(propertiesToInclude) {
return this.toDatalessObject(propertiesToInclude);
},
toObject: function(propertiesToInclude) {
return this._toObjectMethod("toObject", propertiesToInclude);
},
toDatalessObject: function(propertiesToInclude) {
return this._toObjectMethod("toDatalessObject", propertiesToInclude);
},
_toObjectMethod: function(methodName, propertiesToInclude) {
var data = {
objects: this._toObjects(methodName, propertiesToInclude)
};
extend(data, this.__serializeBgOverlay(methodName, propertiesToInclude));
fabric.util.populateWithProperties(this, data, propertiesToInclude);
return data;
},
_toObjects: function(methodName, propertiesToInclude) {
return this.getObjects().filter(function(object) {
return !object.excludeFromExport;
}).map(function(instance) {
return this._toObject(instance, methodName, propertiesToInclude);
}, this);
},
_toObject: function(instance, methodName, propertiesToInclude) {
var originalValue;
if (!this.includeDefaultValues) {
originalValue = instance.includeDefaultValues;
instance.includeDefaultValues = false;
}
var object = instance[methodName](propertiesToInclude);
if (!this.includeDefaultValues) {
instance.includeDefaultValues = originalValue;
}
return object;
},
__serializeBgOverlay: function(methodName, propertiesToInclude) {
var data = {
background: this.backgroundColor && this.backgroundColor.toObject ? this.backgroundColor.toObject(propertiesToInclude) : this.backgroundColor
};
if (this.overlayColor) {
data.overlay = this.overlayColor.toObject ? this.overlayColor.toObject(propertiesToInclude) : this.overlayColor;
}
if (this.backgroundImage) {
data.backgroundImage = this._toObject(this.backgroundImage, methodName, propertiesToInclude);
}
if (this.overlayImage) {
data.overlayImage = this._toObject(this.overlayImage, methodName, propertiesToInclude);
}
return data;
},
svgViewportTransformation: true,
toSVG: function(options, reviver) {
options || (options = {});
var markup = [];
this._setSVGPreamble(markup, options);
this._setSVGHeader(markup, options);
this._setSVGBgOverlayColor(markup, "backgroundColor");
this._setSVGBgOverlayImage(markup, "backgroundImage", reviver);
this._setSVGObjects(markup, reviver);
this._setSVGBgOverlayColor(markup, "overlayColor");
this._setSVGBgOverlayImage(markup, "overlayImage", reviver);
markup.push("</svg>");
return markup.join("");
},
_setSVGPreamble: function(markup, options) {
if (options.suppressPreamble) {
return;
}
markup.push('<?xml version="1.0" encoding="', options.encoding || "UTF-8", '" standalone="no" ?>\n', '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" ', '"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n');
},
_setSVGHeader: function(markup, options) {
var width = options.width || this.width, height = options.height || this.height, vpt, viewBox = 'viewBox="0 0 ' + this.width + " " + this.height + '" ', NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;
if (options.viewBox) {
viewBox = 'viewBox="' + options.viewBox.x + " " + options.viewBox.y + " " + options.viewBox.width + " " + options.viewBox.height + '" ';
} else {
if (this.svgViewportTransformation) {
vpt = this.viewportTransform;
viewBox = 'viewBox="' + toFixed(-vpt[4] / vpt[0], NUM_FRACTION_DIGITS) + " " + toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS) + " " + toFixed(this.width / vpt[0], NUM_FRACTION_DIGITS) + " " + toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS) + '" ';
}
}
markup.push("<svg ", 'xmlns="http://www.w3.org/2000/svg" ', 'xmlns:xlink="http://www.w3.org/1999/xlink" ', 'version="1.1" ', 'width="', width, '" ', 'height="', height, '" ', this.backgroundColor && !this.backgroundColor.toLive ? 'style="background-color: ' + this.backgroundColor + '" ' : null, viewBox, 'xml:space="preserve">\n', "<desc>Created with Fabric.js ", fabric.version, "</desc>\n", "<defs>", fabric.createSVGFontFacesMarkup(this.getObjects()), fabric.createSVGRefElementsMarkup(this), "</defs>\n");
},
_setSVGObjects: function(markup, reviver) {
var instance;
for (var i = 0, objects = this.getObjects(), len = objects.length; i < len; i++) {
instance = objects[i];
if (instance.excludeFromExport) {
continue;
}
this._setSVGObject(markup, instance, reviver);
}
},
_setSVGObject: function(markup, instance, reviver) {
markup.push(instance.toSVG(reviver));
},
_setSVGBgOverlayImage: function(markup, property, reviver) {
if (this[property] && this[property].toSVG) {
markup.push(this[property].toSVG(reviver));
}
},
_setSVGBgOverlayColor: function(markup, property) {
if (this[property] && this[property].source) {
markup.push('<rect x="', this[property].offsetX, '" y="', this[property].offsetY, '" ', 'width="', this[property].repeat === "repeat-y" || this[property].repeat === "no-repeat" ? this[property].source.width : this.width, '" height="', this[property].repeat === "repeat-x" || this[property].repeat === "no-repeat" ? this[property].source.height : this.height, '" fill="url(#' + property + 'Pattern)"', "></rect>\n");
} else if (this[property] && property === "overlayColor") {
markup.push('<rect x="0" y="0" ', 'width="', this.width, '" height="', this.height, '" fill="', this[property], '"', "></rect>\n");
}
},
sendToBack: function(object) {
if (!object) {
return this;
}
var activeGroup = this._activeGroup, i, obj, objs;
if (object === activeGroup) {
objs = activeGroup._objects;
for (i = objs.length; i--; ) {
obj = objs[i];
removeFromArray(this._objects, obj);
this._objects.unshift(obj);
}
} else {
removeFromArray(this._objects, object);
this._objects.unshift(object);
}
return this.renderAll && this.renderAll();
},
bringToFront: function(object) {
if (!object) {
return this;
}
var activeGroup = this._activeGroup, i, obj, objs;
if (object === activeGroup) {
objs = activeGroup._objects;
for (i = 0; i < objs.length; i++) {
obj = objs[i];
removeFromArray(this._objects, obj);
this._objects.push(obj);
}
} else {
removeFromArray(this._objects, object);
this._objects.push(object);
}
return this.renderAll && this.renderAll();
},
sendBackwards: function(object, intersecting) {
if (!object) {
return this;
}
var activeGroup = this._activeGroup, i, obj, idx, newIdx, objs;
if (object === activeGroup) {
objs = activeGroup._objects;
for (i = 0; i < objs.length; i++) {
obj = objs[i];
idx = this._objects.indexOf(obj);
if (idx !== 0) {
newIdx = idx - 1;
removeFromArray(this._objects, obj);
this._objects.splice(newIdx, 0, obj);
}
}
} else {
idx = this._objects.indexOf(object);
if (idx !== 0) {
newIdx = this._findNewLowerIndex(object, idx, intersecting);
removeFromArray(this._objects, object);
this._objects.splice(newIdx, 0, object);
}
}
this.renderAll && this.renderAll();
return this;
},
_findNewLowerIndex: function(object, idx, intersecting) {
var newIdx;
if (intersecting) {
newIdx = idx;
for (var i = idx - 1; i >= 0; --i) {
var isIntersecting = object.intersectsWithObject(this._objects[i]) || object.isContainedWithinObject(this._objects[i]) || this._objects[i].isContainedWithinObject(object);
if (isIntersecting) {
newIdx = i;
break;
}
}
} else {
newIdx = idx - 1;
}
return newIdx;
},
bringForward: function(object, intersecting) {
if (!object) {
return this;
}
var activeGroup = this._activeGroup, i, obj, idx, newIdx, objs;
if (object === activeGroup) {
objs = activeGroup._objects;
for (i = objs.length; i--; ) {
obj = objs[i];
idx = this._objects.indexOf(obj);
if (idx !== this._objects.length - 1) {
newIdx = idx + 1;
removeFromArray(this._objects, obj);
this._objects.splice(newIdx, 0, obj);
}
}
} else {
idx = this._objects.indexOf(object);
if (idx !== this._objects.length - 1) {
newIdx = this._findNewUpperIndex(object, idx, intersecting);
removeFromArray(this._objects, object);
this._objects.splice(newIdx, 0, object);
}
}
this.renderAll && this.renderAll();
return this;
},
_findNewUpperIndex: function(object, idx, intersecting) {
var newIdx;
if (intersecting) {
newIdx = idx;
for (var i = idx + 1; i < this._objects.length; ++i) {
var isIntersecting = object.intersectsWithObject(this._objects[i]) || object.isContainedWithinObject(this._objects[i]) || this._objects[i].isContainedWithinObject(object);
if (isIntersecting) {
newIdx = i;
break;
}
}
} else {
newIdx = idx + 1;
}
return newIdx;
},
moveTo: function(object, index) {
removeFromArray(this._objects, object);
this._objects.splice(index, 0, object);
return this.renderAll && this.renderAll();
},
dispose: function() {
this.clear();
return this;
},
toString: function() {
return "#<fabric.Canvas (" + this.complexity() + "): " + "{ objects: " + this.getObjects().length + " }>";
}
});
extend(fabric.StaticCanvas.prototype, fabric.Observable);
extend(fabric.StaticCanvas.prototype, fabric.Collection);
extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter);
extend(fabric.StaticCanvas, {
EMPTY_JSON: '{"objects": [], "background": "white"}',
supports: function(methodName) {
var el = fabric.util.createCanvasElement();
if (!el || !el.getContext) {
return null;
}
var ctx = el.getContext("2d");
if (!ctx) {
return null;
}
switch (methodName) {
case "getImageData":
return typeof ctx.getImageData !== "undefined";
case "setLineDash":
return typeof ctx.setLineDash !== "undefined";
case "toDataURL":
return typeof el.toDataURL !== "undefined";
case "toDataURLWithQuality":
try {
el.toDataURL("image/jpeg", 0);
return true;
} catch (e) {}
return false;
default:
return null;
}
}
});
fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject;
})();
fabric.BaseBrush = fabric.util.createClass({
color: "rgb(0, 0, 0)",
width: 1,
shadow: null,
strokeLineCap: "round",
strokeLineJoin: "round",
strokeDashArray: null,
setShadow: function(options) {
this.shadow = new fabric.Shadow(options);
return this;
},
_setBrushStyles: function() {
var ctx = this.canvas.contextTop;
ctx.strokeStyle = this.color;
ctx.lineWidth = this.width;
ctx.lineCap = this.strokeLineCap;
ctx.lineJoin = this.strokeLineJoin;
if (this.strokeDashArray && fabric.StaticCanvas.supports("setLineDash")) {
ctx.setLineDash(this.strokeDashArray);
}
},
_setShadow: function() {
if (!this.shadow) {
return;
}
var ctx = this.canvas.contextTop;
ctx.shadowColor = this.shadow.color;
ctx.shadowBlur = this.shadow.blur;
ctx.shadowOffsetX = this.shadow.offsetX;
ctx.shadowOffsetY = this.shadow.offsetY;
},
_resetShadow: function() {
var ctx = this.canvas.contextTop;
ctx.shadowColor = "";
ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;
}
});
(function() {
fabric.PencilBrush = fabric.util.createClass(fabric.BaseBrush, {
initialize: function(canvas) {
this.canvas = canvas;
this._points = [];
},
onMouseDown: function(pointer) {
this._prepareForDrawing(pointer);
this._captureDrawingPath(pointer);
this._render();
},
onMouseMove: function(pointer) {
this._captureDrawingPath(pointer);
this.canvas.clearContext(this.canvas.contextTop);
this._render();
},
onMouseUp: function() {
this._finalizeAndAddPath();
},
_prepareForDrawing: function(pointer) {
var p = new fabric.Point(pointer.x, pointer.y);
this._reset();
this._addPoint(p);
this.canvas.contextTop.moveTo(p.x, p.y);
},
_addPoint: function(point) {
this._points.push(point);
},
_reset: function() {
this._points.length = 0;
this._setBrushStyles();
this._setShadow();
},
_captureDrawingPath: function(pointer) {
var pointerPoint = new fabric.Point(pointer.x, pointer.y);
this._addPoint(pointerPoint);
},
_render: function() {
var ctx = this.canvas.contextTop, v = this.canvas.viewportTransform, p1 = this._points[0], p2 = this._points[1];
ctx.save();
ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
ctx.beginPath();
if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) {
p1.x -= .5;
p2.x += .5;
}
ctx.moveTo(p1.x, p1.y);
for (var i = 1, len = this._points.length; i < len; i++) {
var midPoint = p1.midPointFrom(p2);
ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);
p1 = this._points[i];
p2 = this._points[i + 1];
}
ctx.lineTo(p1.x, p1.y);
ctx.stroke();
ctx.restore();
},
convertPointsToSVGPath: function(points) {
var path = [], p1 = new fabric.Point(points[0].x, points[0].y), p2 = new fabric.Point(points[1].x, points[1].y);
path.push("M ", points[0].x, " ", points[0].y, " ");
for (var i = 1, len = points.length; i < len; i++) {
var midPoint = p1.midPointFrom(p2);
path.push("Q ", p1.x, " ", p1.y, " ", midPoint.x, " ", midPoint.y, " ");
p1 = new fabric.Point(points[i].x, points[i].y);
if (i + 1 < points.length) {
p2 = new fabric.Point(points[i + 1].x, points[i + 1].y);
}
}
path.push("L ", p1.x, " ", p1.y, " ");
return path;
},
createPath: function(pathData) {
var path = new fabric.Path(pathData, {
fill: null,
stroke: this.color,
strokeWidth: this.width,
strokeLineCap: this.strokeLineCap,
strokeLineJoin: this.strokeLineJoin,
strokeDashArray: this.strokeDashArray,
originX: "center",
originY: "center"
});
if (this.shadow) {
this.shadow.affectStroke = true;
path.setShadow(this.shadow);
}
return path;
},
_finalizeAndAddPath: function() {
var ctx = this.canvas.contextTop;
ctx.closePath();
var pathData = this.convertPointsToSVGPath(this._points).join("");
if (pathData === "M 0 0 Q 0 0 0 0 L 0 0") {
this.canvas.renderAll();
return;
}
var path = this.createPath(pathData);
this.canvas.add(path);
path.setCoords();
this.canvas.clearContext(this.canvas.contextTop);
this._resetShadow();
this.canvas.renderAll();
this.canvas.fire("path:created", {
path: path
});
}
});
})();
fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, {
width: 10,
initialize: function(canvas) {
this.canvas = canvas;
this.points = [];
},
drawDot: function(pointer) {
var point = this.addPoint(pointer), ctx = this.canvas.contextTop, v = this.canvas.viewportTransform;
ctx.save();
ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
ctx.fillStyle = point.fill;
ctx.beginPath();
ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false);
ctx.closePath();
ctx.fill();
ctx.restore();
},
onMouseDown: function(pointer) {
this.points.length = 0;
this.canvas.clearContext(this.canvas.contextTop);
this._setShadow();
this.drawDot(pointer);
},
onMouseMove: function(pointer) {
this.drawDot(pointer);
},
onMouseUp: function() {
var originalRenderOnAddRemove = this.canvas.renderOnAddRemove;
this.canvas.renderOnAddRemove = false;
var circles = [];
for (var i = 0, len = this.points.length; i < len; i++) {
var point = this.points[i], circle = new fabric.Circle({
radius: point.radius,
left: point.x,
top: point.y,
originX: "center",
originY: "center",
fill: point.fill
});
this.shadow && circle.setShadow(this.shadow);
circles.push(circle);
}
var group = new fabric.Group(circles, {
originX: "center",
originY: "center"
});
group.canvas = this.canvas;
this.canvas.add(group);
this.canvas.fire("path:created", {
path: group
});
this.canvas.clearContext(this.canvas.contextTop);
this._resetShadow();
this.canvas.renderOnAddRemove = originalRenderOnAddRemove;
this.canvas.renderAll();
},
addPoint: function(pointer) {
var pointerPoint = new fabric.Point(pointer.x, pointer.y), circleRadius = fabric.util.getRandomInt(Math.max(0, this.width - 20), this.width + 20) / 2, circleColor = new fabric.Color(this.color).setAlpha(fabric.util.getRandomInt(0, 100) / 100).toRgba();
pointerPoint.radius = circleRadius;
pointerPoint.fill = circleColor;
this.points.push(pointerPoint);
return pointerPoint;
}
});
fabric.SprayBrush = fabric.util.createClass(fabric.BaseBrush, {
width: 10,
density: 20,
dotWidth: 1,
dotWidthVariance: 1,
randomOpacity: false,
optimizeOverlapping: true,
initialize: function(canvas) {
this.canvas = canvas;
this.sprayChunks = [];
},
onMouseDown: function(pointer) {
this.sprayChunks.length = 0;
this.canvas.clearContext(this.canvas.contextTop);
this._setShadow();
this.addSprayChunk(pointer);
this.render();
},
onMouseMove: function(pointer) {
this.addSprayChunk(pointer);
this.render();
},
onMouseUp: function() {
var originalRenderOnAddRemove = this.canvas.renderOnAddRemove;
this.canvas.renderOnAddRemove = false;
var rects = [];
for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) {
var sprayChunk = this.sprayChunks[i];
for (var j = 0, jlen = sprayChunk.length; j < jlen; j++) {
var rect = new fabric.Rect({
width: sprayChunk[j].width,
height: sprayChunk[j].width,
left: sprayChunk[j].x + 1,
top: sprayChunk[j].y + 1,
originX: "center",
originY: "center",
fill: this.color
});
this.shadow && rect.setShadow(this.shadow);
rects.push(rect);
}
}
if (this.optimizeOverlapping) {
rects = this._getOptimizedRects(rects);
}
var group = new fabric.Group(rects, {
originX: "center",
originY: "center"
});
group.canvas = this.canvas;
this.canvas.add(group);
this.canvas.fire("path:created", {
path: group
});
this.canvas.clearContext(this.canvas.contextTop);
this._resetShadow();
this.canvas.renderOnAddRemove = originalRenderOnAddRemove;
this.canvas.renderAll();
},
_getOptimizedRects: function(rects) {
var uniqueRects = {}, key;
for (var i = 0, len = rects.length; i < len; i++) {
key = rects[i].left + "" + rects[i].top;
if (!uniqueRects[key]) {
uniqueRects[key] = rects[i];
}
}
var uniqueRectsArray = [];
for (key in uniqueRects) {
uniqueRectsArray.push(uniqueRects[key]);
}
return uniqueRectsArray;
},
render: function() {
var ctx = this.canvas.contextTop;
ctx.fillStyle = this.color;
var v = this.canvas.viewportTransform;
ctx.save();
ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
for (var i = 0, len = this.sprayChunkPoints.length; i < len; i++) {
var point = this.sprayChunkPoints[i];
if (typeof point.opacity !== "undefined") {
ctx.globalAlpha = point.opacity;
}
ctx.fillRect(point.x, point.y, point.width, point.width);
}
ctx.restore();
},
addSprayChunk: function(pointer) {
this.sprayChunkPoints = [];
var x, y, width, radius = this.width / 2;
for (var i = 0; i < this.density; i++) {
x = fabric.util.getRandomInt(pointer.x - radius, pointer.x + radius);
y = fabric.util.getRandomInt(pointer.y - radius, pointer.y + radius);
if (this.dotWidthVariance) {
width = fabric.util.getRandomInt(Math.max(1, this.dotWidth - this.dotWidthVariance), this.dotWidth + this.dotWidthVariance);
} else {
width = this.dotWidth;
}
var point = new fabric.Point(x, y);
point.width = width;
if (this.randomOpacity) {
point.opacity = fabric.util.getRandomInt(0, 100) / 100;
}
this.sprayChunkPoints.push(point);
}
this.sprayChunks.push(this.sprayChunkPoints);
}
});
fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, {
getPatternSrc: function() {
var dotWidth = 20, dotDistance = 5, patternCanvas = fabric.document.createElement("canvas"), patternCtx = patternCanvas.getContext("2d");
patternCanvas.width = patternCanvas.height = dotWidth + dotDistance;
patternCtx.fillStyle = this.color;
patternCtx.beginPath();
patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false);
patternCtx.closePath();
patternCtx.fill();
return patternCanvas;
},
getPatternSrcFunction: function() {
return String(this.getPatternSrc).replace("this.color", '"' + this.color + '"');
},
getPattern: function() {
return this.canvas.contextTop.createPattern(this.source || this.getPatternSrc(), "repeat");
},
_setBrushStyles: function() {
this.callSuper("_setBrushStyles");
this.canvas.contextTop.strokeStyle = this.getPattern();
},
createPath: function(pathData) {
var path = this.callSuper("createPath", pathData), topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2);
path.stroke = new fabric.Pattern({
source: this.source || this.getPatternSrcFunction(),
offsetX: -topLeft.x,
offsetY: -topLeft.y
});
return path;
}
});
fabric.MosaicBrush = fabric.util.createClass(fabric.PencilBrush, {
getPatternSrc: function() {
var patternCanvas = fabric.document.createElement("canvas"), patternCtx = patternCanvas.getContext("2d"), lowerCanvas = document.querySelector(this.lowerQuery), realHeight = lowerCanvas.height, realWidth = lowerCanvas.width, upperCanvas = document.querySelector(this.upperQuery), clientHeight = upperCanvas.height, clientWidth = upperCanvas.width, ctx = lowerCanvas.getContext("2d");
var blocksize = this.blocksize || 10;
patternCanvas.width = clientWidth;
patternCanvas.height = clientHeight;
patternCtx.scale(clientWidth / realWidth, clientHeight / realHeight);
patternCtx.drawImage(ctx.canvas, 0, 0);
var imageData = patternCtx.getImageData(0, 0, realWidth, realHeight);
var mosaicData = getMosaicData(imageData, blocksize);
patternCtx.putImageData(mosaicData, 0, 0);
function getMosaicData(imageData, blocksize) {
var data = imageData.data, iLen = imageData.height, jLen = imageData.width, index, i, j, r, g, b, a;
for (i = 0; i < iLen; i += blocksize) {
for (j = 0; j < jLen; j += blocksize) {
index = i * 4 * jLen + j * 4;
r = data[index];
g = data[index + 1];
b = data[index + 2];
a = data[index + 3];
for (var _i = i, _ilen = i + blocksize; _i < _ilen; _i++) {
for (var _j = j, _jlen = j + blocksize; _j < _jlen; _j++) {
index = _i * 4 * jLen + _j * 4;
data[index] = r;
data[index + 1] = g;
data[index + 2] = b;
data[index + 3] = a;
}
}
}
}
return imageData;
}
return patternCanvas;
},
getDataUrlFromPatternSrc: function() {
return {
src: this.getPatternSrc().toDataURL()
};
},
getPatternSrcFunction: function() {
return String(this.getPatternSrc).replace("this.upperQuery", '"' + this.upperQuery + '"').replace("this.lowerQuery", '"' + this.lowerQuery + '"').replace("this.blocksize", this.blocksize);
},
getPattern: function() {
var canvas = this.canvas;
this.upperQuery = fabric.util.Simmer(canvas.upperCanvasEl);
this.lowerQuery = fabric.util.Simmer(canvas.lowerCanvasEl);
this.blocksize = this.blocksize || 10;
return this.canvas.contextTop.createPattern(this.source || this.getPatternSrc(), "repeat");
},
_setBrushStyles: function() {
this.callSuper("_setBrushStyles");
this.canvas.contextTop.strokeStyle = this.getPattern();
},
createPath: function(pathData) {
var path = this.callSuper("createPath", pathData), topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2), source = "";
if (this._mosaic_cache && this._mosaic_cache.mosaicSign === this.mosaicSign) {
source = this._mosaic_cache.source;
} else {
source = this.getPatternSrc();
this._mosaic_cache = {
mosaicSign: this.mosaicSign,
source: source
};
}
path.stroke = new fabric.Pattern({
source: source,
offsetX: -topLeft.x,
offsetY: -topLeft.y
});
return path;
}
});
(function() {
var getPointer = fabric.util.getPointer, degreesToRadians = fabric.util.degreesToRadians, radiansToDegrees = fabric.util.radiansToDegrees, atan2 = Math.atan2, abs = Math.abs, supportLineDash = fabric.StaticCanvas.supports("setLineDash"), STROKE_OFFSET = .5;
fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, {
initialize: function(el, options) {
options || (options = {});
this._initStatic(el, options);
this._initInteractive();
this._createCacheCanvas();
},
uniScaleTransform: false,
uniScaleKey: "shiftKey",
centeredScaling: false,
centeredRotation: false,
centeredKey: "altKey",
altActionKey: "shiftKey",
interactive: true,
selection: true,
selectionKey: "shiftKey",
altSelectionKey: null,
selectionColor: "rgba(100, 100, 255, 0.3)",
selectionDashArray: [],
selectionBorderColor: "rgba(255, 255, 255, 0.3)",
selectionLineWidth: 1,
hoverCursor: "move",
moveCursor: "move",
defaultCursor: "default",
freeDrawingCursor: "crosshair",
rotationCursor: "crosshair",
containerClass: "canvas-container",
perPixelTargetFind: false,
targetFindTolerance: 0,
skipTargetFind: false,
isDrawingMode: false,
preserveObjectStacking: false,
snapAngle: 0,
snapThreshold: null,
stopContextMenu: false,
fireRightClick: false,
_initInteractive: function() {
this._currentTransform = null;
this._groupSelector = null;
this._initWrapperElement();
this._createUpperCanvas();
this._initEventListeners();
this._initRetinaScaling();
this.freeDrawingBrush = fabric.PencilBrush && new fabric.PencilBrush(this);
this.MosaicDrawingBrush = fabric.MosaicBrush && new fabric.MosaicBrush(this);
this.calcOffset();
},
_chooseObjectsToRender: function() {
var activeGroup = this.getActiveGroup(), activeObject = this.getActiveObject(), object, objsToRender = [], activeGroupObjects = [];
if ((activeGroup || activeObject) && !this.preserveObjectStacking) {
for (var i = 0, length = this._objects.length; i < length; i++) {
object = this._objects[i];
if ((!activeGroup || !activeGroup.contains(object)) && object !== activeObject) {
objsToRender.push(object);
} else {
activeGroupObjects.push(object);
}
}
if (activeGroup) {
activeGroup._set("_objects", activeGroupObjects);
objsToRender.push(activeGroup);
}
activeObject && objsToRender.push(activeObject);
} else {
objsToRender = this._objects;
}
return objsToRender;
},
renderAll: function() {
if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) {
this.clearContext(this.contextTop);
this.contextTopDirty = false;
}
var canvasToDrawOn = this.contextContainer;
this.renderCanvas(canvasToDrawOn, this._chooseObjectsToRender());
return this;
},
renderTop: function() {
var ctx = this.contextTop;
this.clearContext(ctx);
if (this.selection && this._groupSelector) {
this._drawSelection(ctx);
}
this.fire("after:render");
this.contextTopDirty = true;
return this;
},
_resetCurrentTransform: function() {
var t = this._currentTransform;
t.target.set({
scaleX: t.original.scaleX,
scaleY: t.original.scaleY,
skewX: t.original.skewX,
skewY: t.original.skewY,
left: t.original.left,
top: t.original.top
});
if (this._shouldCenterTransform(t.target)) {
if (t.action === "rotate" || t.action === "scale&rotate") {
this._setOriginToCenter(t.target);
} else {
if (t.originX !== "center") {
if (t.originX === "right") {
t.mouseXSign = -1;
} else {
t.mouseXSign = 1;
}
}
if (t.originY !== "center") {
if (t.originY === "bottom") {
t.mouseYSign = -1;
} else {
t.mouseYSign = 1;
}
}
t.originX = "center";
t.originY = "center";
}
} else {
t.originX = t.original.originX;
t.originY = t.original.originY;
}
},
containsPoint: function(e, target, point) {
var ignoreZoom = true, pointer = point || this.getPointer(e, ignoreZoom), xy;
if (target.group && target.group === this.getActiveGroup()) {
xy = this._normalizePointer(target.group, pointer);
} else {
xy = {
x: pointer.x,
y: pointer.y
};
}
return target.containsPoint(xy) || target._findTargetCorner(pointer);
},
_normalizePointer: function(object, pointer) {
var m = object.calcTransformMatrix(), invertedM = fabric.util.invertTransform(m), vpt = this.viewportTransform, vptPointer = this.restorePointerVpt(pointer), p = fabric.util.transformPoint(vptPointer, invertedM);
return fabric.util.transformPoint(p, vpt);
},
isTargetTransparent: function(target, x, y) {
var hasBorders = target.hasBorders, transparentCorners = target.transparentCorners, ctx = this.contextCache, originalColor = target.selectionBackgroundColor;
target.hasBorders = target.transparentCorners = false;
target.selectionBackgroundColor = "";
ctx.save();
ctx.transform.apply(ctx, this.viewportTransform);
target.render(ctx);
ctx.restore();
target.active && target._renderControls(ctx);
target.hasBorders = hasBorders;
target.transparentCorners = transparentCorners;
target.selectionBackgroundColor = originalColor;
var isTransparent = fabric.util.isTransparent(ctx, x, y, this.targetFindTolerance);
this.clearContext(ctx);
return isTransparent;
},
_shouldClearSelection: function(e, target) {
var activeGroup = this.getActiveGroup(), activeObject = this.getActiveObject();
return !target || target && activeGroup && !activeGroup.contains(target) && activeGroup !== target && !e[this.selectionKey] || target && !target.evented || target && !target.selectable && activeObject && activeObject !== target;
},
_shouldCenterTransform: function(target) {
if (!target) {
return;
}
var t = this._currentTransform, centerTransform;
if (t.action === "scale" || t.action === "scaleX" || t.action === "scaleY") {
centerTransform = this.centeredScaling || target.centeredScaling;
} else if (t.action === "rotate" || t.action === "scale&rotate") {
centerTransform = this.centeredRotation || target.centeredRotation;
}
return centerTransform ? !t.altKey : t.altKey;
},
_getOriginFromCorner: function(target, corner) {
var origin = {
x: target.originX,
y: target.originY
};
if (corner === "ml" || corner === "tl" || corner === "bl") {
origin.x = "right";
} else if (corner === "mr" || corner === "tr" || corner === "br") {
origin.x = "left";
}
if (corner === "tl" || corner === "mt" || corner === "tr") {
origin.y = "bottom";
} else if (corner === "bl" || corner === "mb" || corner === "br") {
origin.y = "top";
}
return origin;
},
_getActionFromCorner: function(target, corner, e) {
if (!corner) {
return "drag";
}
switch (corner) {
case "mtr":
return "rotate";
case "ml":
case "mr":
return e[this.altActionKey] ? "skewY" : "scaleX";
case "mt":
case "mb":
return e[this.altActionKey] ? "skewX" : "scaleY";
case "tr":
if (target.cornerStyle === "editor") {
return "remove";
}
case "br":
if (target.cornerStyle === "editor") {
return "scale&rotate";
}
default:
return "scale";
}
},
_setupCurrentTransform: function(e, target) {
if (!target) {
return;
}
var pointer = this.getPointer(e), corner = target._findTargetCorner(this.getPointer(e, true)), action = this._getActionFromCorner(target, corner, e), origin = this._getOriginFromCorner(target, corner);
this._currentTransform = {
target: target,
action: action,
corner: corner,
scaleX: target.scaleX,
scaleY: target.scaleY,
skewX: target.skewX,
skewY: target.skewY,
offsetX: pointer.x - target.left,
offsetY: pointer.y - target.top,
originX: origin.x,
originY: origin.y,
ex: pointer.x,
ey: pointer.y,
lastX: pointer.x,
lastY: pointer.y,
left: target.left,
top: target.top,
theta: degreesToRadians(target.angle),
width: target.width * target.scaleX,
mouseXSign: 1,
mouseYSign: 1,
shiftKey: e.shiftKey,
altKey: e[this.centeredKey]
};
this._currentTransform.original = {
left: target.left,
top: target.top,
scaleX: target.scaleX,
scaleY: target.scaleY,
skewX: target.skewX,
skewY: target.skewY,
originX: origin.x,
originY: origin.y
};
this._resetCurrentTransform();
},
_translateObject: function(x, y) {
var transform = this._currentTransform, target = transform.target, newLeft = x - transform.offsetX, newTop = y - transform.offsetY, moveX = !target.get("lockMovementX") && target.left !== newLeft, moveY = !target.get("lockMovementY") && target.top !== newTop;
moveX && target.set("left", newLeft);
moveY && target.set("top", newTop);
return moveX || moveY;
},
_changeSkewTransformOrigin: function(mouseMove, t, by) {
var property = "originX", origins = {
0: "center"
}, skew = t.target.skewX, originA = "left", originB = "right", corner = t.corner === "mt" || t.corner === "ml" ? 1 : -1, flipSign = 1;
mouseMove = mouseMove > 0 ? 1 : -1;
if (by === "y") {
skew = t.target.skewY;
originA = "top";
originB = "bottom";
property = "originY";
}
origins[-1] = originA;
origins[1] = originB;
t.target.flipX && (flipSign *= -1);
t.target.flipY && (flipSign *= -1);
if (skew === 0) {
t.skewSign = -corner * mouseMove * flipSign;
t[property] = origins[-mouseMove];
} else {
skew = skew > 0 ? 1 : -1;
t.skewSign = skew;
t[property] = origins[skew * corner * flipSign];
}
},
_skewObject: function(x, y, by) {
var t = this._currentTransform, target = t.target, skewed = false, lockSkewingX = target.get("lockSkewingX"), lockSkewingY = target.get("lockSkewingY");
if (lockSkewingX && by === "x" || lockSkewingY && by === "y") {
return false;
}
var center = target.getCenterPoint(), actualMouseByCenter = target.toLocalPoint(new fabric.Point(x, y), "center", "center")[by], lastMouseByCenter = target.toLocalPoint(new fabric.Point(t.lastX, t.lastY), "center", "center")[by], actualMouseByOrigin, constraintPosition, dim = target._getTransformedDimensions();
this._changeSkewTransformOrigin(actualMouseByCenter - lastMouseByCenter, t, by);
actualMouseByOrigin = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY)[by];
constraintPosition = target.translateToOriginPoint(center, t.originX, t.originY);
skewed = this._setObjectSkew(actualMouseByOrigin, t, by, dim);
t.lastX = x;
t.lastY = y;
target.setPositionByOrigin(constraintPosition, t.originX, t.originY);
return skewed;
},
_setObjectSkew: function(localMouse, transform, by, _dim) {
var target = transform.target, newValue, skewed = false, skewSign = transform.skewSign, newDim, dimNoSkew, otherBy, _otherBy, _by, newDimMouse, skewX, skewY;
if (by === "x") {
otherBy = "y";
_otherBy = "Y";
_by = "X";
skewX = 0;
skewY = target.skewY;
} else {
otherBy = "x";
_otherBy = "X";
_by = "Y";
skewX = target.skewX;
skewY = 0;
}
dimNoSkew = target._getTransformedDimensions(skewX, skewY);
newDimMouse = 2 * Math.abs(localMouse) - dimNoSkew[by];
if (newDimMouse <= 2) {
newValue = 0;
} else {
newValue = skewSign * Math.atan(newDimMouse / target["scale" + _by] / (dimNoSkew[otherBy] / target["scale" + _otherBy]));
newValue = fabric.util.radiansToDegrees(newValue);
}
skewed = target["skew" + _by] !== newValue;
target.set("skew" + _by, newValue);
if (target["skew" + _otherBy] !== 0) {
newDim = target._getTransformedDimensions();
newValue = _dim[otherBy] / newDim[otherBy] * target["scale" + _otherBy];
target.set("scale" + _otherBy, newValue);
}
return skewed;
},
_scaleObject: function(x, y, by) {
var t = this._currentTransform, target = t.target, lockScalingX = target.get("lockScalingX"), lockScalingY = target.get("lockScalingY"), lockScalingFlip = target.get("lockScalingFlip");
if (lockScalingX && lockScalingY) {
return false;
}
var constraintPosition = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY), localMouse = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY), dim = target._getTransformedDimensions(), scaled = false;
this._setLocalMouse(localMouse, t);
scaled = this._setObjectScale(localMouse, t, lockScalingX, lockScalingY, by, lockScalingFlip, dim);
target.setPositionByOrigin(constraintPosition, t.originX, t.originY);
return scaled;
},
_setObjectScale: function(localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip, _dim) {
var target = transform.target, forbidScalingX = false, forbidScalingY = false, scaled = false, changeX, changeY, scaleX, scaleY;
scaleX = localMouse.x * target.scaleX / _dim.x;
scaleY = localMouse.y * target.scaleY / _dim.y;
changeX = target.scaleX !== scaleX;
changeY = target.scaleY !== scaleY;
if (lockScalingFlip && scaleX <= 0 && scaleX < target.scaleX) {
forbidScalingX = true;
}
if (lockScalingFlip && scaleY <= 0 && scaleY < target.scaleY) {
forbidScalingY = true;
}
if (by === "equally" && !lockScalingX && !lockScalingY) {
forbidScalingX || forbidScalingY || (scaled = this._scaleObjectEqually(localMouse, target, transform, _dim));
} else if (!by) {
forbidScalingX || lockScalingX || target.set("scaleX", scaleX) && (scaled = scaled || changeX);
forbidScalingY || lockScalingY || target.set("scaleY", scaleY) && (scaled = scaled || changeY);
} else if (by === "x" && !target.get("lockUniScaling")) {
forbidScalingX || lockScalingX || target.set("scaleX", scaleX) && (scaled = scaled || changeX);
} else if (by === "y" && !target.get("lockUniScaling")) {
forbidScalingY || lockScalingY || target.set("scaleY", scaleY) && (scaled = scaled || changeY);
}
transform.newScaleX = scaleX;
transform.newScaleY = scaleY;
forbidScalingX || forbidScalingY || this._flipObject(transform, by);
return scaled;
},
_scaleObjectEqually: function(localMouse, target, transform, _dim) {
var dist = localMouse.y + localMouse.x, lastDist = _dim.y * transform.original.scaleY / target.scaleY + _dim.x * transform.original.scaleX / target.scaleX, scaled;
transform.newScaleX = transform.original.scaleX * dist / lastDist;
transform.newScaleY = transform.original.scaleY * dist / lastDist;
scaled = transform.newScaleX !== target.scaleX || transform.newScaleY !== target.scaleY;
target.set("scaleX", transform.newScaleX);
target.set("scaleY", transform.newScaleY);
return scaled;
},
_flipObject: function(transform, by) {
if (transform.newScaleX < 0 && by !== "y") {
if (transform.originX === "left") {
transform.originX = "right";
} else if (transform.originX === "right") {
transform.originX = "left";
}
}
if (transform.newScaleY < 0 && by !== "x") {
if (transform.originY === "top") {
transform.originY = "bottom";
} else if (transform.originY === "bottom") {
transform.originY = "top";
}
}
},
_setLocalMouse: function(localMouse, t) {
var target = t.target;
if (t.originX === "right") {
localMouse.x *= -1;
} else if (t.originX === "center") {
localMouse.x *= t.mouseXSign * 2;
if (localMouse.x < 0) {
t.mouseXSign = -t.mouseXSign;
}
}
if (t.originY === "bottom") {
localMouse.y *= -1;
} else if (t.originY === "center") {
localMouse.y *= t.mouseYSign * 2;
if (localMouse.y < 0) {
t.mouseYSign = -t.mouseYSign;
}
}
if (abs(localMouse.x) > target.padding) {
if (localMouse.x < 0) {
localMouse.x += target.padding;
} else {
localMouse.x -= target.padding;
}
} else {
localMouse.x = 0;
}
if (abs(localMouse.y) > target.padding) {
if (localMouse.y < 0) {
localMouse.y += target.padding;
} else {
localMouse.y -= target.padding;
}
} else {
localMouse.y = 0;
}
},
_rotateObject: function(x, y) {
var t = this._currentTransform;
if (t.target.get("lockRotation")) {
return false;
}
var lastAngle = atan2(t.ey - t.top, t.ex - t.left), curAngle = atan2(y - t.top, x - t.left), angle = radiansToDegrees(curAngle - lastAngle + t.theta), hasRoated = true;
angle = this._checkRotateLock(angle, 0);
angle = this._checkRotateLock(angle, 90);
angle = this._checkRotateLock(angle, 180);
angle = this._checkRotateLock(angle, 270);
if (angle < 0) {
angle = 360 + angle;
}
angle %= 360;
if (t.target.snapAngle > 0) {
var snapAngle = t.target.snapAngle, snapThreshold = t.target.snapThreshold || snapAngle, rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle, leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle;
if (Math.abs(angle - leftAngleLocked) < snapThreshold) {
angle = leftAngleLocked;
} else if (Math.abs(angle - rightAngleLocked) < snapThreshold) {
angle = rightAngleLocked;
}
if (t.target.angle === angle) {
hasRoated = false;
}
}
t.target.angle = angle;
return hasRoated;
},
_checkRotateLock: function(angle, lockAngle, area) {
area = area ? area : 5;
if (Math.abs(Math.abs(angle) - lockAngle) < area) {
this.fire("object:rotateFix", {
angle: lockAngle
});
return angle < 0 ? lockAngle * -1 : lockAngle;
} else {
return angle;
}
},
setCursor: function(value) {
this.upperCanvasEl.style.cursor = value;
},
_resetObjectTransform: function(target) {
target.scaleX = 1;
target.scaleY = 1;
target.skewX = 0;
target.skewY = 0;
target.setAngle(0);
},
_drawSelection: function(ctx) {
var groupSelector = this._groupSelector, left = groupSelector.left, top = groupSelector.top, aleft = abs(left), atop = abs(top);
if (this.selectionColor) {
ctx.fillStyle = this.selectionColor;
ctx.fillRect(groupSelector.ex - (left > 0 ? 0 : -left), groupSelector.ey - (top > 0 ? 0 : -top), aleft, atop);
}
if (!this.selectionLineWidth || !this.selectionBorderColor) {
return;
}
ctx.lineWidth = this.selectionLineWidth;
ctx.strokeStyle = this.selectionBorderColor;
if (this.selectionDashArray.length > 1 && !supportLineDash) {
var px = groupSelector.ex + STROKE_OFFSET - (left > 0 ? 0 : aleft), py = groupSelector.ey + STROKE_OFFSET - (top > 0 ? 0 : atop);
ctx.beginPath();
fabric.util.drawDashedLine(ctx, px, py, px + aleft, py, this.selectionDashArray);
fabric.util.drawDashedLine(ctx, px, py + atop - 1, px + aleft, py + atop - 1, this.selectionDashArray);
fabric.util.drawDashedLine(ctx, px, py, px, py + atop, this.selectionDashArray);
fabric.util.drawDashedLine(ctx, px + aleft - 1, py, px + aleft - 1, py + atop, this.selectionDashArray);
ctx.closePath();
ctx.stroke();
} else {
fabric.Object.prototype._setLineDash.call(this, ctx, this.selectionDashArray);
ctx.strokeRect(groupSelector.ex + STROKE_OFFSET - (left > 0 ? 0 : aleft), groupSelector.ey + STROKE_OFFSET - (top > 0 ? 0 : atop), aleft, atop);
}
},
findTarget: function(e, skipGroup) {
if (this.skipTargetFind) {
return;
}
var ignoreZoom = true, pointer = this.getPointer(e, ignoreZoom), activeGroup = this.getActiveGroup(), activeObject = this.getActiveObject(), activeTarget;
if (activeGroup && !skipGroup && this._checkTarget(pointer, activeGroup)) {
this._fireOverOutEvents(activeGroup, e);
return activeGroup;
}
if (activeObject && activeObject._findTargetCorner(pointer)) {
this._fireOverOutEvents(activeObject, e);
return activeObject;
}
if (activeObject && this._checkTarget(pointer, activeObject)) {
if (!this.preserveObjectStacking) {
this._fireOverOutEvents(activeObject, e);
return activeObject;
} else {
activeTarget = activeObject;
}
}
this.targets = [];
var target = this._searchPossibleTargets(this._objects, pointer);
if (e[this.altSelectionKey] && target && activeTarget && target !== activeTarget) {
target = activeTarget;
}
this._fireOverOutEvents(target, e);
return target;
},
_fireOverOutEvents: function(target, e) {
if (target) {
if (this._hoveredTarget !== target) {
if (this._hoveredTarget) {
this.fire("mouse:out", {
target: this._hoveredTarget,
e: e
});
this._hoveredTarget.fire("mouseout");
}
this.fire("mouse:over", {
target: target,
e: e
});
target.fire("mouseover");
this._hoveredTarget = target;
}
} else if (this._hoveredTarget) {
this.fire("mouse:out", {
target: this._hoveredTarget,
e: e
});
this._hoveredTarget.fire("mouseout");
this._hoveredTarget = null;
}
},
_checkTarget: function(pointer, obj) {
if (obj && obj.visible && obj.evented && this.containsPoint(null, obj, pointer)) {
if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) {
var isTransparent = this.isTargetTransparent(obj, pointer.x, pointer.y);
if (!isTransparent) {
return true;
}
} else {
return true;
}
}
},
_searchPossibleTargets: function(objects, pointer) {
var target, i = objects.length, normalizedPointer, subTarget;
while (i--) {
if (this._checkTarget(pointer, objects[i])) {
target = objects[i];
if (target.type === "group" && target.subTargetCheck) {
normalizedPointer = this._normalizePointer(target, pointer);
subTarget = this._searchPossibleTargets(target._objects, normalizedPointer);
subTarget && this.targets.push(subTarget);
}
break;
}
}
return target;
},
restorePointerVpt: function(pointer) {
return fabric.util.transformPoint(pointer, fabric.util.invertTransform(this.viewportTransform));
},
getPointer: function(e, ignoreZoom, upperCanvasEl) {
if (!upperCanvasEl) {
upperCanvasEl = this.upperCanvasEl;
}
var pointer = getPointer(e), bounds = upperCanvasEl.getBoundingClientRect(), boundsWidth = bounds.width || 0, boundsHeight = bounds.height || 0, cssScale;
if (!boundsWidth || !boundsHeight) {
if ("top" in bounds && "bottom" in bounds) {
boundsHeight = Math.abs(bounds.top - bounds.bottom);
}
if ("right" in bounds && "left" in bounds) {
boundsWidth = Math.abs(bounds.right - bounds.left);
}
}
this.calcOffset();
pointer.x = pointer.x - this._offset.left;
pointer.y = pointer.y - this._offset.top;
if (!ignoreZoom) {
pointer = this.restorePointerVpt(pointer);
}
if (boundsWidth === 0 || boundsHeight === 0) {
cssScale = {
width: 1,
height: 1
};
} else {
cssScale = {
width: upperCanvasEl.width / boundsWidth,
height: upperCanvasEl.height / boundsHeight
};
}
return {
x: pointer.x * cssScale.width,
y: pointer.y * cssScale.height
};
},
_createUpperCanvas: function() {
var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/, "");
this.upperCanvasEl = this._createCanvasElement();
fabric.util.addClass(this.upperCanvasEl, "upper-canvas " + lowerCanvasClass);
this.wrapperEl.appendChild(this.upperCanvasEl);
this._copyCanvasStyle(this.lowerCanvasEl, this.upperCanvasEl);
this._applyCanvasStyle(this.upperCanvasEl);
this.contextTop = this.upperCanvasEl.getContext("2d");
},
_createCacheCanvas: function() {
this.cacheCanvasEl = this._createCanvasElement();
this.cacheCanvasEl.setAttribute("width", this.width);
this.cacheCanvasEl.setAttribute("height", this.height);
this.contextCache = this.cacheCanvasEl.getContext("2d");
},
_initWrapperElement: function() {
this.wrapperEl = fabric.util.wrapElement(this.lowerCanvasEl, "div", {
class: this.containerClass
});
fabric.util.setStyle(this.wrapperEl, {
width: this.getWidth() + "px",
height: this.getHeight() + "px",
position: "relative"
});
fabric.util.makeElementUnselectable(this.wrapperEl);
},
_applyCanvasStyle: function(element) {
var width = this.getWidth() || element.width, height = this.getHeight() || element.height;
fabric.util.setStyle(element, {
position: "absolute",
width: width + "px",
height: height + "px",
left: 0,
top: 0
});
element.width = width;
element.height = height;
fabric.util.makeElementUnselectable(element);
},
_copyCanvasStyle: function(fromEl, toEl) {
toEl.style.cssText = fromEl.style.cssText;
},
getSelectionContext: function() {
return this.contextTop;
},
getSelectionElement: function() {
return this.upperCanvasEl;
},
_setActiveObject: function(object) {
if (this._activeObject) {
this._activeObject.set("active", false);
}
this._activeObject = object;
object.set("active", true);
},
setActiveObject: function(object, e) {
this._setActiveObject(object);
this.renderAll();
this.fire("object:selected", {
target: object,
e: e
});
object.fire("selected", {
e: e
});
return this;
},
getActiveObject: function() {
return this._activeObject;
},
_onObjectRemoved: function(obj) {
if (this.getActiveObject() === obj) {
this.fire("before:selection:cleared", {
target: obj
});
this._discardActiveObject();
this.fire("selection:cleared", {
target: obj
});
obj.fire("deselected");
}
this.callSuper("_onObjectRemoved", obj);
},
_discardActiveObject: function() {
if (this._activeObject) {
this._activeObject.set("active", false);
}
this._activeObject = null;
},
discardActiveObject: function(e) {
var activeObject = this._activeObject;
this.fire("before:selection:cleared", {
target: activeObject,
e: e
});
this._discardActiveObject();
this.fire("selection:cleared", {
e: e
});
activeObject && activeObject.fire("deselected", {
e: e
});
return this;
},
_setActiveGroup: function(group) {
this._activeGroup = group;
if (group) {
group.set("active", true);
}
},
setActiveGroup: function(group, e) {
this._setActiveGroup(group);
if (group) {
this.fire("object:selected", {
target: group,
e: e
});
group.fire("selected", {
e: e
});
}
return this;
},
getActiveGroup: function() {
return this._activeGroup;
},
_discardActiveGroup: function() {
var g = this.getActiveGroup();
if (g) {
g.destroy();
}
this.setActiveGroup(null);
},
discardActiveGroup: function(e) {
var g = this.getActiveGroup();
this.fire("before:selection:cleared", {
e: e,
target: g
});
this._discardActiveGroup();
this.fire("selection:cleared", {
e: e
});
return this;
},
deactivateAll: function() {
var allObjects = this.getObjects(), i = 0, len = allObjects.length;
for (;i < len; i++) {
allObjects[i].set("active", false);
}
this._discardActiveGroup();
this._discardActiveObject();
return this;
},
deactivateAllWithDispatch: function(e) {
var activeGroup = this.getActiveGroup(), activeObject = this.getActiveObject();
if (activeObject || activeGroup) {
this.fire("before:selection:cleared", {
target: activeObject || activeGroup,
e: e
});
}
this.deactivateAll();
if (activeObject || activeGroup) {
this.fire("selection:cleared", {
e: e,
target: activeObject
});
activeObject && activeObject.fire("deselected");
}
return this;
},
dispose: function() {
this.callSuper("dispose");
var wrapper = this.wrapperEl;
this.removeListeners();
wrapper.removeChild(this.upperCanvasEl);
wrapper.removeChild(this.lowerCanvasEl);
delete this.upperCanvasEl;
if (wrapper.parentNode) {
wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl);
}
delete this.wrapperEl;
return this;
},
clear: function() {
this.discardActiveGroup();
this.discardActiveObject();
this.clearContext(this.contextTop);
return this.callSuper("clear");
},
drawControls: function(ctx) {
var activeGroup = this.getActiveGroup();
if (activeGroup) {
activeGroup._renderControls(ctx);
} else {
this._drawObjectsControls(ctx);
}
},
_drawObjectsControls: function(ctx) {
for (var i = 0, len = this._objects.length; i < len; ++i) {
if (!this._objects[i] || !this._objects[i].active) {
continue;
}
this._objects[i]._renderControls(ctx);
}
},
_toObject: function(instance, methodName, propertiesToInclude) {
var originalProperties = this._realizeGroupTransformOnObject(instance), object = this.callSuper("_toObject", instance, methodName, propertiesToInclude);
this._unwindGroupTransformOnObject(instance, originalProperties);
return object;
},
_realizeGroupTransformOnObject: function(instance) {
var layoutProps = [ "angle", "flipX", "flipY", "height", "left", "scaleX", "scaleY", "top", "width" ];
if (instance.group && instance.group === this.getActiveGroup()) {
var originalValues = {};
layoutProps.forEach(function(prop) {
originalValues[prop] = instance[prop];
});
this.getActiveGroup().realizeTransform(instance);
return originalValues;
} else {
return null;
}
},
_unwindGroupTransformOnObject: function(instance, originalValues) {
if (originalValues) {
instance.set(originalValues);
}
},
_setSVGObject: function(markup, instance, reviver) {
var originalProperties;
originalProperties = this._realizeGroupTransformOnObject(instance);
this.callSuper("_setSVGObject", markup, instance, reviver);
this._unwindGroupTransformOnObject(instance, originalProperties);
}
});
for (var prop in fabric.StaticCanvas) {
if (prop !== "prototype") {
fabric.Canvas[prop] = fabric.StaticCanvas[prop];
}
}
if (fabric.isTouchSupported) {
fabric.Canvas.prototype._setCursorFromEvent = function() {};
}
fabric.Element = fabric.Canvas;
})();
(function() {
var cursorOffset = {
mt: 0,
tr: 1,
mr: 2,
br: 3,
mb: 4,
bl: 5,
ml: 6,
tl: 7
}, addListener = fabric.util.addListener, removeListener = fabric.util.removeListener;
fabric.util.object.extend(fabric.Canvas.prototype, {
cursorMap: [ "n-resize", "ne-resize", "e-resize", "se-resize", "s-resize", "sw-resize", "w-resize", "nw-resize" ],
_initEventListeners: function() {
this._bindEvents();
addListener(fabric.window, "resize", this._onResize);
addListener(this.upperCanvasEl, "mousedown", this._onMouseDown);
addListener(this.upperCanvasEl, "mousemove", this._onMouseMove);
addListener(this.upperCanvasEl, "mouseout", this._onMouseOut);
addListener(this.upperCanvasEl, "mouseenter", this._onMouseEnter);
addListener(this.upperCanvasEl, "wheel", this._onMouseWheel);
addListener(this.upperCanvasEl, "contextmenu", this._onContextMenu);
addListener(this.upperCanvasEl, "touchstart", this._onMouseDown);
addListener(this.upperCanvasEl, "touchmove", this._onMouseMove);
if (typeof eventjs !== "undefined" && "add" in eventjs) {
eventjs.add(this.upperCanvasEl, "gesture", this._onGesture);
eventjs.add(this.upperCanvasEl, "drag", this._onDrag);
eventjs.add(this.upperCanvasEl, "orientation", this._onOrientationChange);
eventjs.add(this.upperCanvasEl, "shake", this._onShake);
eventjs.add(this.upperCanvasEl, "longpress", this._onLongPress);
}
},
_bindEvents: function() {
this._onMouseDown = this._onMouseDown.bind(this);
this._onMouseMove = this._onMouseMove.bind(this);
this._onMouseUp = this._onMouseUp.bind(this);
this._onResize = this._onResize.bind(this);
this._onGesture = this._onGesture.bind(this);
this._onDrag = this._onDrag.bind(this);
this._onShake = this._onShake.bind(this);
this._onLongPress = this._onLongPress.bind(this);
this._onOrientationChange = this._onOrientationChange.bind(this);
this._onMouseWheel = this._onMouseWheel.bind(this);
this._onMouseOut = this._onMouseOut.bind(this);
this._onMouseEnter = this._onMouseEnter.bind(this);
this._onContextMenu = this._onContextMenu.bind(this);
},
removeListeners: function() {
removeListener(fabric.window, "resize", this._onResize);
removeListener(this.upperCanvasEl, "mousedown", this._onMouseDown);
removeListener(this.upperCanvasEl, "mousemove", this._onMouseMove);
removeListener(this.upperCanvasEl, "mouseout", this._onMouseOut);
removeListener(this.upperCanvasEl, "mouseenter", this._onMouseEnter);
removeListener(this.upperCanvasEl, "wheel", this._onMouseWheel);
removeListener(this.upperCanvasEl, "contextmenu", this._onContextMenu);
removeListener(this.upperCanvasEl, "touchstart", this._onMouseDown);
removeListener(this.upperCanvasEl, "touchmove", this._onMouseMove);
if (typeof eventjs !== "undefined" && "remove" in eventjs) {
eventjs.remove(this.upperCanvasEl, "gesture", this._onGesture);
eventjs.remove(this.upperCanvasEl, "drag", this._onDrag);
eventjs.remove(this.upperCanvasEl, "orientation", this._onOrientationChange);
eventjs.remove(this.upperCanvasEl, "shake", this._onShake);
eventjs.remove(this.upperCanvasEl, "longpress", this._onLongPress);
}
},
_onGesture: function(e, self) {
this.__onTransformGesture && this.__onTransformGesture(e, self);
},
_onDrag: function(e, self) {
this.__onDrag && this.__onDrag(e, self);
},
_onMouseWheel: function(e) {
this.__onMouseWheel(e);
},
_onMouseOut: function(e) {
var target = this._hoveredTarget;
this.fire("mouse:out", {
target: target,
e: e
});
this._hoveredTarget = null;
target && target.fire("mouseout", {
e: e
});
},
_onMouseEnter: function(e) {
if (!this.findTarget(e)) {
this.fire("mouse:over", {
target: null,
e: e
});
this._hoveredTarget = null;
}
},
_onOrientationChange: function(e, self) {
this.__onOrientationChange && this.__onOrientationChange(e, self);
},
_onShake: function(e, self) {
this.__onShake && this.__onShake(e, self);
},
_onLongPress: function(e, self) {
this.__onLongPress && this.__onLongPress(e, self);
},
_onContextMenu: function(e) {
if (this.stopContextMenu) {
e.stopPropagation();
e.preventDefault();
}
return false;
},
_onMouseDown: function(e) {
this.__onMouseDown(e);
addListener(fabric.document, "touchend", this._onMouseUp);
addListener(fabric.document, "touchmove", this._onMouseMove);
removeListener(this.upperCanvasEl, "mousemove", this._onMouseMove);
removeListener(this.upperCanvasEl, "touchmove", this._onMouseMove);
if (e.type === "touchstart") {
removeListener(this.upperCanvasEl, "mousedown", this._onMouseDown);
} else {
addListener(fabric.document, "mouseup", this._onMouseUp);
addListener(fabric.document, "mousemove", this._onMouseMove);
}
},
_onMouseUp: function(e) {
this.__onMouseUp(e);
removeListener(fabric.document, "mouseup", this._onMouseUp);
removeListener(fabric.document, "touchend", this._onMouseUp);
removeListener(fabric.document, "mousemove", this._onMouseMove);
removeListener(fabric.document, "touchmove", this._onMouseMove);
addListener(this.upperCanvasEl, "mousemove", this._onMouseMove);
addListener(this.upperCanvasEl, "touchmove", this._onMouseMove);
if (e.type === "touchend") {
var _this = this;
setTimeout(function() {
addListener(_this.upperCanvasEl, "mousedown", _this._onMouseDown);
}, 400);
}
},
_onMouseMove: function(e) {
this.__onMouseMove(e);
},
_onResize: function() {
this.calcOffset();
},
_shouldRender: function(target, pointer) {
var activeObject = this.getActiveGroup() || this.getActiveObject();
return !!(target && (target.isMoving || target !== activeObject) || !target && !!activeObject || !target && !activeObject && !this._groupSelector || pointer && this._previousPointer && this.selection && (pointer.x !== this._previousPointer.x || pointer.y !== this._previousPointer.y));
},
__onMouseUp: function(e) {
var target, searchTarget = true, transform = this._currentTransform, groupSelector = this._groupSelector, isClick = !groupSelector || groupSelector.left === 0 && groupSelector.top === 0;
if (this.isDrawingMode && this._isCurrentlyDrawing) {
this._onMouseUpInDrawingMode(e);
return;
}
if (transform) {
this._finalizeCurrentTransform();
searchTarget = !transform.actionPerformed;
}
target = searchTarget ? this.findTarget(e, true) : transform.target;
var shouldRender = this._shouldRender(target, this.getPointer(e));
if (target || !isClick) {
this._maybeGroupObjects(e);
} else {
this._groupSelector = null;
this._currentTransform = null;
}
if (target) {
target.isMoving = false;
if (target.cornerStyle === "editor") {
var corner = target._findTargetCorner(this.getPointer(e, true));
if (corner === "tr") {
this.fire("object:remove", target);
return;
}
}
}
this._handleCursorAndEvent(e, target, "up");
target && (target.__corner = 0);
shouldRender && this.renderAll();
},
_handleCursorAndEvent: function(e, target, eventType) {
this._setCursorFromEvent(e, target);
this._handleEvent(e, eventType, target ? target : null);
},
_handleEvent: function(e, eventType, targetObj) {
var target = typeof targetObj === undefined ? this.findTarget(e) : targetObj, targets = this.targets || [], options = {
e: e,
target: target,
subTargets: targets
};
this.fire("mouse:" + eventType, options);
target && target.fire("mouse" + eventType, options);
for (var i = 0; i < targets.length; i++) {
targets[i].fire("mouse" + eventType, options);
}
},
_finalizeCurrentTransform: function() {
var transform = this._currentTransform, target = transform.target;
if (target._scaling) {
target._scaling = false;
}
target.setCoords();
this._restoreOriginXY(target);
if (transform.actionPerformed || this.stateful && target.hasStateChanged()) {
this.fire("object:modified", {
target: target
});
target.fire("modified");
}
},
_restoreOriginXY: function(target) {
if (this._previousOriginX && this._previousOriginY) {
var originPoint = target.translateToOriginPoint(target.getCenterPoint(), this._previousOriginX, this._previousOriginY);
target.originX = this._previousOriginX;
target.originY = this._previousOriginY;
target.left = originPoint.x;
target.top = originPoint.y;
this._previousOriginX = null;
this._previousOriginY = null;
}
},
_onMouseDownInDrawingMode: function(e) {
this._isCurrentlyDrawing = true;
this.discardActiveObject(e).renderAll();
if (this.clipTo) {
fabric.util.clipContext(this, this.contextTop);
}
var pointer = this.getPointer(e);
this.freeDrawingBrush.onMouseDown(pointer);
this._handleEvent(e, "down");
},
_onMouseMoveInDrawingMode: function(e) {
if (this._isCurrentlyDrawing) {
var pointer = this.getPointer(e);
this.freeDrawingBrush.onMouseMove(pointer);
}
this.setCursor(this.freeDrawingCursor);
this._handleEvent(e, "move");
},
_onMouseUpInDrawingMode: function(e) {
this._isCurrentlyDrawing = false;
if (this.clipTo) {
this.contextTop.restore();
}
this.freeDrawingBrush.onMouseUp();
this._handleEvent(e, "up");
},
__onMouseDown: function(e) {
var target = this.findTarget(e), pointer = this.getPointer(e, true);
var isRightClick = "which" in e ? e.which === 3 : e.button === 2;
if (isRightClick) {
if (this.fireRightClick) {
this._handleEvent(e, "down", target ? target : null);
}
return;
}
if (this.isDrawingMode) {
this._onMouseDownInDrawingMode(e);
return;
}
if (this._currentTransform) {
return;
}
this._previousPointer = pointer;
var shouldRender = this._shouldRender(target, pointer), shouldGroup = this._shouldGroup(e, target);
if (this._shouldClearSelection(e, target)) {
this._clearSelection(e, target, pointer);
} else if (shouldGroup) {
this._handleGrouping(e, target);
target = this.getActiveGroup();
}
if (target) {
if (target.selectable && (target.__corner || !shouldGroup)) {
this._beforeTransform(e, target);
this._setupCurrentTransform(e, target);
}
if (target !== this.getActiveGroup() && target !== this.getActiveObject()) {
this.deactivateAll();
target.selectable && this.setActiveObject(target, e);
}
}
this._handleEvent(e, "down", target ? target : null);
shouldRender && this.renderAll();
},
_beforeTransform: function(e, target) {
this.stateful && target.saveState();
if (target._findTargetCorner(this.getPointer(e))) {
this.onBeforeScaleRotate(target);
}
},
_clearSelection: function(e, target, pointer) {
this.deactivateAllWithDispatch(e);
if (target && target.selectable) {
this.setActiveObject(target, e);
} else if (this.selection) {
this._groupSelector = {
ex: pointer.x,
ey: pointer.y,
top: 0,
left: 0
};
}
},
_setOriginToCenter: function(target) {
this._previousOriginX = this._currentTransform.target.originX;
this._previousOriginY = this._currentTransform.target.originY;
var center = target.getCenterPoint();
target.originX = "center";
target.originY = "center";
target.left = center.x;
target.top = center.y;
this._currentTransform.left = target.left;
this._currentTransform.top = target.top;
},
_setCenterToOrigin: function(target) {
var originPoint = target.translateToOriginPoint(target.getCenterPoint(), this._previousOriginX, this._previousOriginY);
target.originX = this._previousOriginX;
target.originY = this._previousOriginY;
target.left = originPoint.x;
target.top = originPoint.y;
this._previousOriginX = null;
this._previousOriginY = null;
},
__onMouseMove: function(e) {
var target, pointer;
if (this.isDrawingMode) {
this._onMouseMoveInDrawingMode(e);
return;
}
if (typeof e.touches !== "undefined" && e.touches.length > 1) {
return;
}
var groupSelector = this._groupSelector;
if (groupSelector) {
if (!this.noSelector) {
pointer = this.getPointer(e, true);
groupSelector.left = pointer.x - groupSelector.ex;
groupSelector.top = pointer.y - groupSelector.ey;
this.renderTop();
}
} else if (!this._currentTransform) {
target = this.findTarget(e);
this._setCursorFromEvent(e, target);
} else {
this._transformObject(e);
}
this._handleEvent(e, "move", target ? target : null);
},
__onMouseWheel: function(e) {
this.fire("mouse:wheel", {
e: e
});
},
_transformObject: function(e) {
var pointer = this.getPointer(e), transform = this._currentTransform;
transform.reset = false;
transform.target.isMoving = true;
this._beforeScaleTransform(e, transform);
this._performTransformAction(e, transform, pointer);
transform.actionPerformed && this.renderAll();
},
_performTransformAction: function(e, transform, pointer) {
var x = pointer.x, y = pointer.y, target = transform.target, action = transform.action, actionPerformed = false;
if (action === "rotate") {
(actionPerformed = this._rotateObject(x, y)) && this._fire("rotating", target, e);
} else if (action === "scale&rotate") {
(actionPerformed = this._rotateObject(x, y)) && this._fire("rotating", target, e);
(actionPerformed = this._onScale(e, transform, x, y)) && this._fire("scaling", target, e);
} else if (action === "scale") {
(actionPerformed = this._onScale(e, transform, x, y)) && this._fire("scaling", target, e);
} else if (action === "remove") {} else if (action === "scaleX") {
(actionPerformed = this._scaleObject(x, y, "x")) && this._fire("scaling", target, e);
} else if (action === "scaleY") {
(actionPerformed = this._scaleObject(x, y, "y")) && this._fire("scaling", target, e);
} else if (action === "skewX") {
(actionPerformed = this._skewObject(x, y, "x")) && this._fire("skewing", target, e);
} else if (action === "skewY") {
(actionPerformed = this._skewObject(x, y, "y")) && this._fire("skewing", target, e);
} else {
actionPerformed = this._translateObject(x, y);
if (actionPerformed) {
this._fire("moving", target, e);
this.setCursor(target.moveCursor || this.moveCursor);
}
}
transform.actionPerformed = actionPerformed;
},
_fire: function(eventName, target, e) {
this.fire("object:" + eventName, {
target: target,
e: e
});
target.fire(eventName, {
e: e
});
},
_beforeScaleTransform: function(e, transform) {
if (transform.action === "scale" || transform.action === "scaleX" || transform.action === "scaleY") {
var centerTransform = this._shouldCenterTransform(transform.target);
if (centerTransform && (transform.originX !== "center" || transform.originY !== "center") || !centerTransform && transform.originX === "center" && transform.originY === "center") {
this._resetCurrentTransform();
transform.reset = true;
}
}
},
_onScale: function(e, transform, x, y) {
if ((e[this.uniScaleKey] || this.uniScaleTransform) && !transform.target.get("lockUniScaling")) {
transform.currentAction = "scale";
return this._scaleObject(x, y);
} else {
if (!transform.reset && transform.currentAction === "scale") {
this._resetCurrentTransform();
}
transform.currentAction = "scaleEqually";
return this._scaleObject(x, y, "equally");
}
},
_setCursorFromEvent: function(e, target) {
if (!target) {
this.setCursor(this.defaultCursor);
return false;
}
var hoverCursor = target.hoverCursor || this.hoverCursor;
if (!target.selectable) {
this.setCursor(hoverCursor);
} else {
var activeGroup = this.getActiveGroup(), corner = target._findTargetCorner && (!activeGroup || !activeGroup.contains(target)) && target._findTargetCorner(this.getPointer(e, true));
if (!corner) {
this.setCursor(hoverCursor);
} else {
this._setCornerCursor(corner, target, e);
}
}
return true;
},
_setCornerCursor: function(corner, target, e) {
if (corner in cursorOffset) {
this.setCursor(this._getRotatedCornerCursor(corner, target, e));
} else if (corner === "mtr" && target.hasRotatingPoint) {
this.setCursor(this.rotationCursor);
} else {
this.setCursor(this.defaultCursor);
return false;
}
},
_getRotatedCornerCursor: function(corner, target, e) {
var n = Math.round(target.getAngle() % 360 / 45);
if (n < 0) {
n += 8;
}
n += cursorOffset[corner];
if (e[this.altActionKey] && cursorOffset[corner] % 2 === 0) {
n += 2;
}
n %= 8;
return this.cursorMap[n];
}
});
})();
(function() {
var min = Math.min, max = Math.max;
fabric.util.object.extend(fabric.Canvas.prototype, {
_shouldGroup: function(e, target) {
var activeObject = this.getActiveObject();
return e[this.selectionKey] && target && target.selectable && (this.getActiveGroup() || activeObject && activeObject !== target) && this.selection;
},
_handleGrouping: function(e, target) {
var activeGroup = this.getActiveGroup();
if (target === activeGroup) {
target = this.findTarget(e, true);
if (!target) {
return;
}
}
if (activeGroup) {
this._updateActiveGroup(target, e);
} else {
this._createActiveGroup(target, e);
}
if (this._activeGroup) {
this._activeGroup.saveCoords();
}
},
_updateActiveGroup: function(target, e) {
var activeGroup = this.getActiveGroup();
if (activeGroup.contains(target)) {
activeGroup.removeWithUpdate(target);
target.set("active", false);
if (activeGroup.size() === 1) {
this.discardActiveGroup(e);
this.setActiveObject(activeGroup.item(0));
return;
}
} else {
activeGroup.addWithUpdate(target);
}
this.fire("selection:created", {
target: activeGroup,
e: e
});
activeGroup.set("active", true);
},
_createActiveGroup: function(target, e) {
if (this._activeObject && target !== this._activeObject) {
var group = this._createGroup(target);
group.addWithUpdate();
this.setActiveGroup(group);
this._activeObject = null;
this.fire("selection:created", {
target: group,
e: e
});
}
target.set("active", true);
},
_createGroup: function(target) {
var objects = this.getObjects(), isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target), groupObjects = isActiveLower ? [ this._activeObject, target ] : [ target, this._activeObject ];
this._activeObject.isEditing && this._activeObject.exitEditing();
return new fabric.Group(groupObjects, {
canvas: this
});
},
_groupSelectedObjects: function(e) {
var group = this._collectObjects();
if (group.length === 1) {
this.setActiveObject(group[0], e);
} else if (group.length > 1) {
group = new fabric.Group(group.reverse(), {
canvas: this
});
group.addWithUpdate();
this.setActiveGroup(group, e);
group.saveCoords();
this.fire("selection:created", {
target: group
});
this.renderAll();
}
},
_collectObjects: function() {
var group = [], currentObject, x1 = this._groupSelector.ex, y1 = this._groupSelector.ey, x2 = x1 + this._groupSelector.left, y2 = y1 + this._groupSelector.top, selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)), selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)), isClick = x1 === x2 && y1 === y2;
for (var i = this._objects.length; i--; ) {
currentObject = this._objects[i];
if (!currentObject || !currentObject.selectable || !currentObject.visible) {
continue;
}
if (currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2) || currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) || currentObject.containsPoint(selectionX1Y1) || currentObject.containsPoint(selectionX2Y2)) {
currentObject.set("active", true);
group.push(currentObject);
if (isClick) {
break;
}
}
}
return group;
},
_maybeGroupObjects: function(e) {
if (this.selection && this._groupSelector) {
this._groupSelectedObjects(e);
}
var activeGroup = this.getActiveGroup();
if (activeGroup) {
activeGroup.setObjectsCoords().setCoords();
activeGroup.isMoving = false;
this.setCursor(this.defaultCursor);
}
this._groupSelector = null;
this._currentTransform = null;
}
});
})();
(function() {
var supportQuality = fabric.StaticCanvas.supports("toDataURLWithQuality");
fabric.util.object.extend(fabric.StaticCanvas.prototype, {
toDataURL: function(options) {
options || (options = {});
var format = options.format || "png", quality = options.quality || 1, multiplier = options.multiplier || 1, cropping = {
left: options.left || 0,
top: options.top || 0,
width: options.width || 0,
height: options.height || 0
};
return this.__toDataURLWithMultiplier(format, quality, cropping, multiplier);
},
__toDataURLWithMultiplier: function(format, quality, cropping, multiplier) {
var origWidth = this.getWidth(), origHeight = this.getHeight(), scaledWidth = (cropping.width || this.getWidth()) * multiplier, scaledHeight = (cropping.height || this.getHeight()) * multiplier, zoom = this.getZoom(), newZoom = zoom * multiplier, vp = this.viewportTransform, translateX = (vp[4] - cropping.left) * multiplier, translateY = (vp[5] - cropping.top) * multiplier, newVp = [ newZoom, 0, 0, newZoom, translateX, translateY ], originalInteractive = this.interactive;
this.viewportTransform = newVp;
this.interactive && (this.interactive = false);
if (origWidth !== scaledWidth || origHeight !== scaledHeight) {
this.setDimensions({
width: scaledWidth,
height: scaledHeight
});
} else {
this.renderAll();
}
var data = this.__toDataURL(format, quality, cropping);
originalInteractive && (this.interactive = originalInteractive);
this.viewportTransform = vp;
this.setDimensions({
width: origWidth,
height: origHeight
});
return data;
},
__toDataURL: function(format, quality) {
var canvasEl = this.contextContainer.canvas;
if (format === "jpg") {
format = "jpeg";
}
var data = supportQuality ? canvasEl.toDataURL("image/" + format, quality) : canvasEl.toDataURL("image/" + format);
return data;
},
toDataURLWithMultiplier: function(format, multiplier, quality) {
return this.toDataURL({
format: format,
multiplier: multiplier,
quality: quality
});
}
});
})();
fabric.util.object.extend(fabric.StaticCanvas.prototype, {
loadFromDatalessJSON: function(json, callback, reviver) {
return this.loadFromJSON(json, callback, reviver);
},
loadFromJSON: function(json, callback, reviver) {
if (!json) {
return;
}
var serialized = typeof json === "string" ? JSON.parse(json) : fabric.util.object.clone(json);
this.clear();
var _this = this;
this._enlivenObjects(serialized.objects, function() {
_this._setBgOverlay(serialized, function() {
delete serialized.objects;
delete serialized.backgroundImage;
delete serialized.overlayImage;
delete serialized.background;
delete serialized.overlay;
for (var prop in serialized) {
_this[prop] = serialized[prop];
}
callback && callback();
});
}, reviver);
return this;
},
_setBgOverlay: function(serialized, callback) {
var _this = this, loaded = {
backgroundColor: false,
overlayColor: false,
backgroundImage: false,
overlayImage: false
};
if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background && !serialized.overlay) {
callback && callback();
return;
}
var cbIfLoaded = function() {
if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) {
_this.renderAll();
callback && callback();
}
};
this.__setBgOverlay("backgroundImage", serialized.backgroundImage, loaded, cbIfLoaded);
this.__setBgOverlay("overlayImage", serialized.overlayImage, loaded, cbIfLoaded);
this.__setBgOverlay("backgroundColor", serialized.background, loaded, cbIfLoaded);
this.__setBgOverlay("overlayColor", serialized.overlay, loaded, cbIfLoaded);
cbIfLoaded();
},
__setBgOverlay: function(property, value, loaded, callback) {
var _this = this;
if (!value) {
loaded[property] = true;
return;
}
if (property === "backgroundImage" || property === "overlayImage") {
fabric.Image.fromObject(value, function(img) {
_this[property] = img;
loaded[property] = true;
callback && callback();
});
} else {
this["set" + fabric.util.string.capitalize(property, true)](value, function() {
loaded[property] = true;
callback && callback();
});
}
},
_enlivenObjects: function(objects, callback, reviver) {
var _this = this;
if (!objects || objects.length === 0) {
callback && callback();
return;
}
var renderOnAddRemove = this.renderOnAddRemove;
this.renderOnAddRemove = false;
fabric.util.enlivenObjects(objects, function(enlivenedObjects) {
enlivenedObjects.forEach(function(obj, index) {
_this.insertAt(obj, index);
});
_this.renderOnAddRemove = renderOnAddRemove;
callback && callback();
}, null, reviver);
},
_toDataURL: function(format, callback) {
this.clone(function(clone) {
callback(clone.toDataURL(format));
});
},
_toDataURLWithMultiplier: function(format, multiplier, callback) {
this.clone(function(clone) {
callback(clone.toDataURLWithMultiplier(format, multiplier));
});
},
clone: function(callback, properties) {
var data = JSON.stringify(this.toJSON(properties));
this.cloneWithoutData(function(clone) {
clone.loadFromJSON(data, function() {
callback && callback(clone);
});
});
},
cloneWithoutData: function(callback) {
var el = fabric.document.createElement("canvas");
el.width = this.getWidth();
el.height = this.getHeight();
var clone = new fabric.Canvas(el);
clone.clipTo = this.clipTo;
if (this.backgroundImage) {
clone.setBackgroundImage(this.backgroundImage.src, function() {
clone.renderAll();
callback && callback(clone);
});
clone.backgroundImageOpacity = this.backgroundImageOpacity;
clone.backgroundImageStretch = this.backgroundImageStretch;
} else {
callback && callback(clone);
}
}
});
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, toFixed = fabric.util.toFixed, capitalize = fabric.util.string.capitalize, degreesToRadians = fabric.util.degreesToRadians, supportsLineDash = fabric.StaticCanvas.supports("setLineDash");
if (fabric.Object) {
return;
}
fabric.Object = fabric.util.createClass({
type: "object",
originX: "left",
originY: "top",
top: 0,
left: 0,
width: 0,
height: 0,
scaleX: 1,
scaleY: 1,
flipX: false,
flipY: false,
opacity: 1,
angle: 0,
skewX: 0,
skewY: 0,
cornerSize: 13,
transparentCorners: true,
hoverCursor: null,
moveCursor: null,
padding: 0,
borderColor: "rgba(102,153,255,0.75)",
borderDashArray: null,
cornerColor: "rgba(102,153,255,0.5)",
cornerStrokeColor: null,
cornerStyle: "rect",
cornerDashArray: null,
centeredScaling: false,
centeredRotation: true,
fill: "rgb(0,0,0)",
fillRule: "nonzero",
globalCompositeOperation: "source-over",
backgroundColor: "",
selectionBackgroundColor: "",
stroke: null,
strokeWidth: 1,
strokeDashArray: null,
strokeLineCap: "butt",
strokeLineJoin: "miter",
strokeMiterLimit: 10,
shadow: null,
borderOpacityWhenMoving: .4,
borderScaleFactor: 1,
transformMatrix: null,
minScaleLimit: .01,
selectable: true,
evented: true,
visible: true,
hasControls: true,
hasBorders: true,
hasRotatingPoint: true,
rotatingPointOffset: 40,
perPixelTargetFind: false,
includeDefaultValues: true,
clipTo: null,
lockMovementX: false,
lockMovementY: false,
lockRotation: false,
lockScalingX: false,
lockScalingY: false,
lockUniScaling: false,
lockSkewingX: false,
lockSkewingY: false,
lockScalingFlip: false,
excludeFromExport: false,
stateProperties: ("top left width height scaleX scaleY flipX flipY originX originY transformMatrix " + "stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit " + "angle opacity fill fillRule globalCompositeOperation shadow clipTo visible backgroundColor " + "skewX skewY").split(" "),
initialize: function(options) {
if (options) {
this.setOptions(options);
}
},
_initGradient: function(options) {
if (options.fill && options.fill.colorStops && !(options.fill instanceof fabric.Gradient)) {
this.set("fill", new fabric.Gradient(options.fill));
}
if (options.stroke && options.stroke.colorStops && !(options.stroke instanceof fabric.Gradient)) {
this.set("stroke", new fabric.Gradient(options.stroke));
}
},
_initPattern: function(options) {
if (options.fill && options.fill.source && !(options.fill instanceof fabric.Pattern)) {
this.set("fill", new fabric.Pattern(options.fill));
}
if (options.stroke && options.stroke.source && !(options.stroke instanceof fabric.Pattern)) {
this.set("stroke", new fabric.Pattern(options.stroke));
}
},
_initClipping: function(options) {
if (!options.clipTo || typeof options.clipTo !== "string") {
return;
}
var functionBody = fabric.util.getFunctionBody(options.clipTo);
if (typeof functionBody !== "undefined") {
this.clipTo = new Function("ctx", functionBody);
}
},
setOptions: function(options) {
for (var prop in options) {
this.set(prop, options[prop]);
}
this._initGradient(options);
this._initPattern(options);
this._initClipping(options);
},
transform: function(ctx, fromLeft) {
if (this.group && !this.group._transformDone && this.group === this.canvas._activeGroup) {
this.group.transform(ctx);
}
var center = fromLeft ? this._getLeftTopCoords() : this.getCenterPoint();
ctx.translate(center.x, center.y);
ctx.rotate(degreesToRadians(this.angle));
ctx.scale(this.scaleX * (this.flipX ? -1 : 1), this.scaleY * (this.flipY ? -1 : 1));
ctx.transform(1, 0, Math.tan(degreesToRadians(this.skewX)), 1, 0, 0);
ctx.transform(1, Math.tan(degreesToRadians(this.skewY)), 0, 1, 0, 0);
},
toObject: function(propertiesToInclude) {
var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, object = {
type: this.type,
originX: this.originX,
originY: this.originY,
left: toFixed(this.left, NUM_FRACTION_DIGITS),
top: toFixed(this.top, NUM_FRACTION_DIGITS),
width: toFixed(this.width, NUM_FRACTION_DIGITS),
height: toFixed(this.height, NUM_FRACTION_DIGITS),
fill: this.fill && this.fill.toObject ? this.fill.toObject() : this.fill,
stroke: this.stroke && this.stroke.toObject ? this.stroke.toObject() : this.stroke,
strokeWidth: toFixed(this.strokeWidth, NUM_FRACTION_DIGITS),
strokeDashArray: this.strokeDashArray ? this.strokeDashArray.concat() : this.strokeDashArray,
strokeLineCap: this.strokeLineCap,
strokeLineJoin: this.strokeLineJoin,
strokeMiterLimit: toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS),
scaleX: toFixed(this.scaleX, NUM_FRACTION_DIGITS),
scaleY: toFixed(this.scaleY, NUM_FRACTION_DIGITS),
angle: toFixed(this.getAngle(), NUM_FRACTION_DIGITS),
flipX: this.flipX,
flipY: this.flipY,
opacity: toFixed(this.opacity, NUM_FRACTION_DIGITS),
shadow: this.shadow && this.shadow.toObject ? this.shadow.toObject() : this.shadow,
visible: this.visible,
clipTo: this.clipTo && String(this.clipTo),
backgroundColor: this.backgroundColor,
fillRule: this.fillRule,
globalCompositeOperation: this.globalCompositeOperation,
transformMatrix: this.transformMatrix ? this.transformMatrix.concat() : this.transformMatrix,
skewX: toFixed(this.skewX, NUM_FRACTION_DIGITS),
skewY: toFixed(this.skewY, NUM_FRACTION_DIGITS)
};
fabric.util.populateWithProperties(this, object, propertiesToInclude);
if (!this.includeDefaultValues) {
object = this._removeDefaultValues(object);
}
return object;
},
toDatalessObject: function(propertiesToInclude) {
return this.toObject(propertiesToInclude);
},
_removeDefaultValues: function(object) {
var prototype = fabric.util.getKlass(object.type).prototype, stateProperties = prototype.stateProperties;
stateProperties.forEach(function(prop) {
if (object[prop] === prototype[prop]) {
delete object[prop];
}
var isArray = Object.prototype.toString.call(object[prop]) === "[object Array]" && Object.prototype.toString.call(prototype[prop]) === "[object Array]";
if (isArray && object[prop].length === 0 && prototype[prop].length === 0) {
delete object[prop];
}
});
return object;
},
toString: function() {
return "#<fabric." + capitalize(this.type) + ">";
},
get: function(property) {
return this[property];
},
getObjectScaling: function() {
var scaleX = this.scaleX, scaleY = this.scaleY;
if (this.group) {
var scaling = this.group.getObjectScaling();
scaleX *= scaling.scaleX;
scaleY *= scaling.scaleY;
}
return {
scaleX: scaleX,
scaleY: scaleY
};
},
_setObject: function(obj) {
for (var prop in obj) {
this._set(prop, obj[prop]);
}
},
set: function(key, value) {
if (typeof key === "object") {
this._setObject(key);
} else {
if (typeof value === "function" && key !== "clipTo") {
this._set(key, value(this.get(key)));
} else {
this._set(key, value);
}
}
return this;
},
_set: function(key, value) {
var shouldConstrainValue = key === "scaleX" || key === "scaleY";
if (shouldConstrainValue) {
value = this._constrainScale(value);
}
if (key === "scaleX" && value < 0) {
this.flipX = !this.flipX;
value *= -1;
} else if (key === "scaleY" && value < 0) {
this.flipY = !this.flipY;
value *= -1;
} else if (key === "shadow" && value && !(value instanceof fabric.Shadow)) {
value = new fabric.Shadow(value);
}
this[key] = value;
if (key === "width" || key === "height") {
this.minScaleLimit = Math.min(.1, 1 / Math.max(this.width, this.height));
}
return this;
},
setOnGroup: function() {},
toggle: function(property) {
var value = this.get(property);
if (typeof value === "boolean") {
this.set(property, !value);
}
return this;
},
setSourcePath: function(value) {
this.sourcePath = value;
return this;
},
getViewportTransform: function() {
if (this.canvas && this.canvas.viewportTransform) {
return this.canvas.viewportTransform;
}
return [ 1, 0, 0, 1, 0, 0 ];
},
render: function(ctx, noTransform) {
if (this.width === 0 && this.height === 0 || !this.visible) {
return;
}
ctx.save();
this._setupCompositeOperation(ctx);
this.drawSelectionBackground(ctx);
if (!noTransform) {
this.transform(ctx);
}
this._setOpacity(ctx);
this._setShadow(ctx);
this._renderBackground(ctx);
this._setStrokeStyles(ctx);
this._setFillStyles(ctx);
if (this.transformMatrix) {
ctx.transform.apply(ctx, this.transformMatrix);
}
this.clipTo && fabric.util.clipContext(this, ctx);
this._render(ctx, noTransform);
this.clipTo && ctx.restore();
ctx.restore();
},
_renderBackground: function(ctx) {
if (!this.backgroundColor) {
return;
}
ctx.fillStyle = this.backgroundColor;
ctx.fillRect(-this.width / 2, -this.height / 2, this.width, this.height);
this._removeShadow(ctx);
},
_setOpacity: function(ctx) {
if (this.group) {
this.group._setOpacity(ctx);
}
ctx.globalAlpha *= this.opacity;
},
_setStrokeStyles: function(ctx) {
if (this.stroke) {
ctx.lineWidth = this.strokeWidth;
ctx.lineCap = this.strokeLineCap;
ctx.lineJoin = this.strokeLineJoin;
ctx.miterLimit = this.strokeMiterLimit;
ctx.strokeStyle = this.stroke.toLive ? this.stroke.toLive(ctx, this) : this.stroke;
}
},
_setFillStyles: function(ctx) {
if (this.fill) {
ctx.fillStyle = this.fill.toLive ? this.fill.toLive(ctx, this) : this.fill;
}
},
_setLineDash: function(ctx, dashArray, alternative) {
if (!dashArray) {
return;
}
if (1 & dashArray.length) {
dashArray.push.apply(dashArray, dashArray);
}
if (supportsLineDash) {
ctx.setLineDash(dashArray);
} else {
alternative && alternative(ctx);
}
},
_renderControls: function(ctx, noTransform) {
if (!this.active || noTransform || this.group && this.group !== this.canvas.getActiveGroup()) {
return;
}
var vpt = this.getViewportTransform(), matrix = this.calcTransformMatrix(), options;
matrix = fabric.util.multiplyTransformMatrices(vpt, matrix);
options = fabric.util.qrDecompose(matrix);
ctx.save();
ctx.translate(options.translateX, options.translateY);
ctx.lineWidth = 1 * this.borderScaleFactor;
ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;
if (this.group && this.group === this.canvas.getActiveGroup()) {
ctx.rotate(degreesToRadians(options.angle));
this.drawBordersInGroup(ctx, options);
} else {
ctx.rotate(degreesToRadians(this.angle));
this.drawBorders(ctx);
}
this.drawControls(ctx);
ctx.restore();
},
_setShadow: function(ctx) {
if (!this.shadow) {
return;
}
var multX = this.canvas && this.canvas.viewportTransform[0] || 1, multY = this.canvas && this.canvas.viewportTransform[3] || 1, scaling = this.getObjectScaling();
if (this.canvas && this.canvas._isRetinaScaling()) {
multX *= fabric.devicePixelRatio;
multY *= fabric.devicePixelRatio;
}
ctx.shadowColor = this.shadow.color;
ctx.shadowBlur = this.shadow.blur * (multX + multY) * (scaling.scaleX + scaling.scaleY) / 4;
ctx.shadowOffsetX = this.shadow.offsetX * multX * scaling.scaleX;
ctx.shadowOffsetY = this.shadow.offsetY * multY * scaling.scaleY;
},
_removeShadow: function(ctx) {
if (!this.shadow) {
return;
}
ctx.shadowColor = "";
ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;
},
_renderFill: function(ctx) {
if (!this.fill) {
return;
}
ctx.save();
if (this.fill.gradientTransform) {
var g = this.fill.gradientTransform;
ctx.transform.apply(ctx, g);
}
if (this.fill.toLive) {
ctx.translate(-this.width / 2 + this.fill.offsetX || 0, -this.height / 2 + this.fill.offsetY || 0);
}
if (this.fillRule === "evenodd") {
ctx.fill("evenodd");
} else {
ctx.fill();
}
ctx.restore();
},
_renderStroke: function(ctx) {
if (!this.stroke || this.strokeWidth === 0) {
return;
}
if (this.shadow && !this.shadow.affectStroke) {
this._removeShadow(ctx);
}
ctx.save();
this._setLineDash(ctx, this.strokeDashArray, this._renderDashedStroke);
if (this.stroke.gradientTransform) {
var g = this.stroke.gradientTransform;
ctx.transform.apply(ctx, g);
}
if (this.stroke.toLive) {
ctx.translate(-this.width / 2 + this.stroke.offsetX || 0, -this.height / 2 + this.stroke.offsetY || 0);
}
ctx.stroke();
ctx.restore();
},
clone: function(callback, propertiesToInclude) {
if (this.constructor.fromObject) {
return this.constructor.fromObject(this.toObject(propertiesToInclude), callback);
}
return new fabric.Object(this.toObject(propertiesToInclude));
},
cloneAsImage: function(callback, options) {
var dataUrl = this.toDataURL(options);
fabric.util.loadImage(dataUrl, function(img) {
if (callback) {
callback(new fabric.Image(img));
}
});
return this;
},
toDataURL: function(options) {
options || (options = {});
var el = fabric.util.createCanvasElement(), boundingRect = this.getBoundingRect();
el.width = boundingRect.width;
el.height = boundingRect.height;
fabric.util.wrapElement(el, "div");
var canvas = new fabric.StaticCanvas(el, {
enableRetinaScaling: options.enableRetinaScaling
});
if (options.format === "jpg") {
options.format = "jpeg";
}
if (options.format === "jpeg") {
canvas.backgroundColor = "#fff";
}
var origParams = {
active: this.get("active"),
left: this.getLeft(),
top: this.getTop()
};
this.set("active", false);
this.setPositionByOrigin(new fabric.Point(canvas.getWidth() / 2, canvas.getHeight() / 2), "center", "center");
var originalCanvas = this.canvas;
canvas.add(this);
var data = canvas.toDataURL(options);
this.set(origParams).setCoords();
this.canvas = originalCanvas;
canvas.dispose();
canvas = null;
return data;
},
isType: function(type) {
return this.type === type;
},
complexity: function() {
return 0;
},
toJSON: function(propertiesToInclude) {
return this.toObject(propertiesToInclude);
},
setGradient: function(property, options) {
options || (options = {});
var gradient = {
colorStops: []
};
gradient.type = options.type || (options.r1 || options.r2 ? "radial" : "linear");
gradient.coords = {
x1: options.x1,
y1: options.y1,
x2: options.x2,
y2: options.y2
};
if (options.r1 || options.r2) {
gradient.coords.r1 = options.r1;
gradient.coords.r2 = options.r2;
}
options.gradientTransform && (gradient.gradientTransform = options.gradientTransform);
for (var position in options.colorStops) {
var color = new fabric.Color(options.colorStops[position]);
gradient.colorStops.push({
offset: position,
color: color.toRgb(),
opacity: color.getAlpha()
});
}
return this.set(property, fabric.Gradient.forObject(this, gradient));
},
setPatternFill: function(options) {
return this.set("fill", new fabric.Pattern(options));
},
setShadow: function(options) {
return this.set("shadow", options ? new fabric.Shadow(options) : null);
},
setColor: function(color) {
this.set("fill", color);
return this;
},
setAngle: function(angle) {
var shouldCenterOrigin = (this.originX !== "center" || this.originY !== "center") && this.centeredRotation;
if (shouldCenterOrigin) {
this._setOriginToCenter();
}
this.set("angle", angle);
if (shouldCenterOrigin) {
this._resetOrigin();
}
return this;
},
centerH: function() {
this.canvas && this.canvas.centerObjectH(this);
return this;
},
viewportCenterH: function() {
this.canvas && this.canvas.viewportCenterObjectH(this);
return this;
},
centerV: function() {
this.canvas && this.canvas.centerObjectV(this);
return this;
},
viewportCenterV: function() {
this.canvas && this.canvas.viewportCenterObjectV(this);
return this;
},
center: function() {
this.canvas && this.canvas.centerObject(this);
return this;
},
viewportCenter: function() {
this.canvas && this.canvas.viewportCenterObject(this);
return this;
},
remove: function() {
this.canvas && this.canvas.remove(this);
return this;
},
getLocalPointer: function(e, pointer) {
pointer = pointer || this.canvas.getPointer(e);
var pClicked = new fabric.Point(pointer.x, pointer.y), objectLeftTop = this._getLeftTopCoords();
if (this.angle) {
pClicked = fabric.util.rotatePoint(pClicked, objectLeftTop, fabric.util.degreesToRadians(-this.angle));
}
return {
x: pClicked.x - objectLeftTop.x,
y: pClicked.y - objectLeftTop.y
};
},
_setupCompositeOperation: function(ctx) {
if (this.globalCompositeOperation) {
ctx.globalCompositeOperation = this.globalCompositeOperation;
}
}
});
fabric.util.createAccessors(fabric.Object);
fabric.Object.prototype.rotate = fabric.Object.prototype.setAngle;
extend(fabric.Object.prototype, fabric.Observable);
fabric.Object.NUM_FRACTION_DIGITS = 2;
fabric.Object.__uid = 0;
})( true ? exports : this);
(function() {
var degreesToRadians = fabric.util.degreesToRadians, originXOffset = {
left: -.5,
center: 0,
right: .5
}, originYOffset = {
top: -.5,
center: 0,
bottom: .5
};
fabric.util.object.extend(fabric.Object.prototype, {
translateToGivenOrigin: function(point, fromOriginX, fromOriginY, toOriginX, toOriginY) {
var x = point.x, y = point.y, offsetX, offsetY, dim;
if (typeof fromOriginX === "string") {
fromOriginX = originXOffset[fromOriginX];
} else {
fromOriginX -= .5;
}
if (typeof toOriginX === "string") {
toOriginX = originXOffset[toOriginX];
} else {
toOriginX -= .5;
}
offsetX = toOriginX - fromOriginX;
if (typeof fromOriginY === "string") {
fromOriginY = originYOffset[fromOriginY];
} else {
fromOriginY -= .5;
}
if (typeof toOriginY === "string") {
toOriginY = originYOffset[toOriginY];
} else {
toOriginY -= .5;
}
offsetY = toOriginY - fromOriginY;
if (offsetX || offsetY) {
dim = this._getTransformedDimensions();
x = point.x + offsetX * dim.x;
y = point.y + offsetY * dim.y;
}
return new fabric.Point(x, y);
},
translateToCenterPoint: function(point, originX, originY) {
var p = this.translateToGivenOrigin(point, originX, originY, "center", "center");
if (this.angle) {
return fabric.util.rotatePoint(p, point, degreesToRadians(this.angle));
}
return p;
},
translateToOriginPoint: function(center, originX, originY) {
var p = this.translateToGivenOrigin(center, "center", "center", originX, originY);
if (this.angle) {
return fabric.util.rotatePoint(p, center, degreesToRadians(this.angle));
}
return p;
},
getCenterPoint: function() {
var leftTop = new fabric.Point(this.left, this.top);
return this.translateToCenterPoint(leftTop, this.originX, this.originY);
},
getPointByOrigin: function(originX, originY) {
var center = this.getCenterPoint();
return this.translateToOriginPoint(center, originX, originY);
},
toLocalPoint: function(point, originX, originY) {
var center = this.getCenterPoint(), p, p2;
if (typeof originX !== "undefined" && typeof originY !== "undefined") {
p = this.translateToGivenOrigin(center, "center", "center", originX, originY);
} else {
p = new fabric.Point(this.left, this.top);
}
p2 = new fabric.Point(point.x, point.y);
if (this.angle) {
p2 = fabric.util.rotatePoint(p2, center, -degreesToRadians(this.angle));
}
return p2.subtractEquals(p);
},
setPositionByOrigin: function(pos, originX, originY) {
var center = this.translateToCenterPoint(pos, originX, originY), position = this.translateToOriginPoint(center, this.originX, this.originY);
this.set("left", position.x);
this.set("top", position.y);
},
adjustPosition: function(to) {
var angle = degreesToRadians(this.angle), hypotFull = this.getWidth(), xFull = Math.cos(angle) * hypotFull, yFull = Math.sin(angle) * hypotFull, offsetFrom, offsetTo;
if (typeof this.originX === "string") {
offsetFrom = originXOffset[this.originX];
} else {
offsetFrom = this.originX - .5;
}
if (typeof to === "string") {
offsetTo = originXOffset[to];
} else {
offsetTo = to - .5;
}
this.left += xFull * (offsetTo - offsetFrom);
this.top += yFull * (offsetTo - offsetFrom);
this.setCoords();
this.originX = to;
},
_setOriginToCenter: function() {
this._originalOriginX = this.originX;
this._originalOriginY = this.originY;
var center = this.getCenterPoint();
this.originX = "center";
this.originY = "center";
this.left = center.x;
this.top = center.y;
},
_resetOrigin: function() {
var originPoint = this.translateToOriginPoint(this.getCenterPoint(), this._originalOriginX, this._originalOriginY);
this.originX = this._originalOriginX;
this.originY = this._originalOriginY;
this.left = originPoint.x;
this.top = originPoint.y;
this._originalOriginX = null;
this._originalOriginY = null;
},
_getLeftTopCoords: function() {
return this.translateToOriginPoint(this.getCenterPoint(), "left", "top");
},
_getRightTopCoords: function() {
return this.translateToOriginPoint(this.getCenterPoint(), "right", "top");
}
});
})();
(function() {
function getCoords(oCoords) {
return [ new fabric.Point(oCoords.tl.x, oCoords.tl.y), new fabric.Point(oCoords.tr.x, oCoords.tr.y), new fabric.Point(oCoords.br.x, oCoords.br.y), new fabric.Point(oCoords.bl.x, oCoords.bl.y) ];
}
var degreesToRadians = fabric.util.degreesToRadians, multiplyMatrices = fabric.util.multiplyTransformMatrices;
fabric.util.object.extend(fabric.Object.prototype, {
oCoords: null,
intersectsWithRect: function(pointTL, pointBR) {
var oCoords = getCoords(this.oCoords), intersection = fabric.Intersection.intersectPolygonRectangle(oCoords, pointTL, pointBR);
return intersection.status === "Intersection";
},
intersectsWithObject: function(other) {
var intersection = fabric.Intersection.intersectPolygonPolygon(getCoords(this.oCoords), getCoords(other.oCoords));
return intersection.status === "Intersection" || other.isContainedWithinObject(this) || this.isContainedWithinObject(other);
},
isContainedWithinObject: function(other) {
var points = getCoords(this.oCoords), i = 0;
for (;i < 4; i++) {
if (!other.containsPoint(points[i])) {
return false;
}
}
return true;
},
isContainedWithinRect: function(pointTL, pointBR) {
var boundingRect = this.getBoundingRect();
return boundingRect.left >= pointTL.x && boundingRect.left + boundingRect.width <= pointBR.x && boundingRect.top >= pointTL.y && boundingRect.top + boundingRect.height <= pointBR.y;
},
containsPoint: function(point) {
if (!this.oCoords) {
this.setCoords();
}
var lines = this._getImageLines(this.oCoords), xPoints = this._findCrossPoints(point, lines);
return xPoints !== 0 && xPoints % 2 === 1;
},
_getImageLines: function(oCoords) {
return {
topline: {
o: oCoords.tl,
d: oCoords.tr
},
rightline: {
o: oCoords.tr,
d: oCoords.br
},
bottomline: {
o: oCoords.br,
d: oCoords.bl
},
leftline: {
o: oCoords.bl,
d: oCoords.tl
}
};
},
_findCrossPoints: function(point, oCoords) {
var b1, b2, a1, a2, xi, xcount = 0, iLine;
for (var lineKey in oCoords) {
iLine = oCoords[lineKey];
if (iLine.o.y < point.y && iLine.d.y < point.y) {
continue;
}
if (iLine.o.y >= point.y && iLine.d.y >= point.y) {
continue;
}
if (iLine.o.x === iLine.d.x && iLine.o.x >= point.x) {
xi = iLine.o.x;
} else {
b1 = 0;
b2 = (iLine.d.y - iLine.o.y) / (iLine.d.x - iLine.o.x);
a1 = point.y - b1 * point.x;
a2 = iLine.o.y - b2 * iLine.o.x;
xi = -(a1 - a2) / (b1 - b2);
}
if (xi >= point.x) {
xcount += 1;
}
if (xcount === 2) {
break;
}
}
return xcount;
},
getBoundingRectWidth: function() {
return this.getBoundingRect().width;
},
getBoundingRectHeight: function() {
return this.getBoundingRect().height;
},
getBoundingRect: function() {
this.oCoords || this.setCoords();
return fabric.util.makeBoundingBoxFromPoints([ this.oCoords.tl, this.oCoords.tr, this.oCoords.br, this.oCoords.bl ]);
},
getWidth: function() {
return this._getTransformedDimensions().x;
},
getHeight: function() {
return this._getTransformedDimensions().y;
},
_constrainScale: function(value) {
if (Math.abs(value) < this.minScaleLimit) {
if (value < 0) {
return -this.minScaleLimit;
} else {
return this.minScaleLimit;
}
}
return value;
},
scale: function(value) {
value = this._constrainScale(value);
if (value < 0) {
this.flipX = !this.flipX;
this.flipY = !this.flipY;
value *= -1;
}
this.scaleX = value;
this.scaleY = value;
this.setCoords();
return this;
},
scaleToWidth: function(value) {
var boundingRectFactor = this.getBoundingRect().width / this.getWidth();
return this.scale(value / this.width / boundingRectFactor);
},
scaleToHeight: function(value) {
var boundingRectFactor = this.getBoundingRect().height / this.getHeight();
return this.scale(value / this.height / boundingRectFactor);
},
setCoords: function() {
var theta = degreesToRadians(this.angle), vpt = this.getViewportTransform(), dim = this._calculateCurrentDimensions(), currentWidth = dim.x, currentHeight = dim.y;
if (currentWidth < 0) {
currentWidth = Math.abs(currentWidth);
}
var sinTh = Math.sin(theta), cosTh = Math.cos(theta), extra = this.cornerStyle === "editor" ? this.cornerSize / 2 : 0;
_angle = currentWidth > 0 ? Math.atan(currentHeight / currentWidth) : 0, _hypotenuse = currentWidth / Math.cos(_angle) / 2,
offsetX = Math.cos(_angle + theta) * _hypotenuse, offsetY = Math.sin(_angle + theta) * _hypotenuse,
coords = fabric.util.transformPoint(this.getCenterPoint(), vpt), tl = new fabric.Point(coords.x - offsetX, coords.y - offsetY),
tr = new fabric.Point(tl.x + extra + currentWidth * cosTh, tl.y + currentWidth * sinTh),
bl = new fabric.Point(tl.x - extra - currentHeight * sinTh, tl.y + currentHeight * cosTh),
br = new fabric.Point(coords.x + offsetX, coords.y + offsetY), ml = new fabric.Point((tl.x + bl.x) / 2, (tl.y + bl.y) / 2),
mt = new fabric.Point((tr.x + tl.x) / 2, (tr.y + tl.y) / 2), mr = new fabric.Point((br.x + tr.x) / 2, (br.y + tr.y) / 2),
mb = new fabric.Point((br.x + bl.x) / 2, (br.y + bl.y) / 2), mtr = new fabric.Point(mt.x + sinTh * this.rotatingPointOffset, mt.y - cosTh * this.rotatingPointOffset);
this.oCoords = {
tl: tl,
tr: tr,
br: br,
bl: bl,
ml: ml,
mt: mt,
mr: mr,
mb: mb,
mtr: mtr
};
this._setCornerCoords && this._setCornerCoords();
return this;
},
_calcRotateMatrix: function() {
if (this.angle) {
var theta = degreesToRadians(this.angle), cos = Math.cos(theta), sin = Math.sin(theta);
return [ cos, sin, -sin, cos, 0, 0 ];
}
return [ 1, 0, 0, 1, 0, 0 ];
},
calcTransformMatrix: function() {
var center = this.getCenterPoint(), translateMatrix = [ 1, 0, 0, 1, center.x, center.y ], rotateMatrix = this._calcRotateMatrix(), dimensionMatrix = this._calcDimensionsTransformMatrix(this.skewX, this.skewY, true), matrix = this.group ? this.group.calcTransformMatrix() : [ 1, 0, 0, 1, 0, 0 ];
matrix = multiplyMatrices(matrix, translateMatrix);
matrix = multiplyMatrices(matrix, rotateMatrix);
matrix = multiplyMatrices(matrix, dimensionMatrix);
return matrix;
},
_calcDimensionsTransformMatrix: function(skewX, skewY, flipping) {
var skewMatrixX = [ 1, 0, Math.tan(degreesToRadians(skewX)), 1 ], skewMatrixY = [ 1, Math.tan(degreesToRadians(skewY)), 0, 1 ], scaleX = this.scaleX * (flipping && this.flipX ? -1 : 1), scaleY = this.scaleY * (flipping && this.flipY ? -1 : 1), scaleMatrix = [ scaleX, 0, 0, scaleY ], m = multiplyMatrices(scaleMatrix, skewMatrixX, true);
return multiplyMatrices(m, skewMatrixY, true);
}
});
})();
fabric.util.object.extend(fabric.Object.prototype, {
sendToBack: function() {
if (this.group) {
fabric.StaticCanvas.prototype.sendToBack.call(this.group, this);
} else {
this.canvas.sendToBack(this);
}
return this;
},
bringToFront: function() {
if (this.group) {
fabric.StaticCanvas.prototype.bringToFront.call(this.group, this);
} else {
this.canvas.bringToFront(this);
}
return this;
},
sendBackwards: function(intersecting) {
if (this.group) {
fabric.StaticCanvas.prototype.sendBackwards.call(this.group, this, intersecting);
} else {
this.canvas.sendBackwards(this, intersecting);
}
return this;
},
bringForward: function(intersecting) {
if (this.group) {
fabric.StaticCanvas.prototype.bringForward.call(this.group, this, intersecting);
} else {
this.canvas.bringForward(this, intersecting);
}
return this;
},
moveTo: function(index) {
if (this.group) {
fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index);
} else {
this.canvas.moveTo(this, index);
}
return this;
}
});
(function() {
function getSvgColorString(prop, value) {
if (!value) {
return prop + ": none; ";
} else if (value.toLive) {
return prop + ": url(#SVGID_" + value.id + "); ";
} else {
var color = new fabric.Color(value), str = prop + ": " + color.toRgb() + "; ", opacity = color.getAlpha();
if (opacity !== 1) {
str += prop + "-opacity: " + opacity.toString() + "; ";
}
return str;
}
}
fabric.util.object.extend(fabric.Object.prototype, {
getSvgStyles: function(skipShadow) {
var fillRule = this.fillRule, strokeWidth = this.strokeWidth ? this.strokeWidth : "0", strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(" ") : "none", strokeLineCap = this.strokeLineCap ? this.strokeLineCap : "butt", strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : "miter", strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : "4", opacity = typeof this.opacity !== "undefined" ? this.opacity : "1", visibility = this.visible ? "" : " visibility: hidden;", filter = skipShadow ? "" : this.getSvgFilter(), fill = getSvgColorString("fill", this.fill), stroke = getSvgColorString("stroke", this.stroke);
return [ stroke, "stroke-width: ", strokeWidth, "; ", "stroke-dasharray: ", strokeDashArray, "; ", "stroke-linecap: ", strokeLineCap, "; ", "stroke-linejoin: ", strokeLineJoin, "; ", "stroke-miterlimit: ", strokeMiterLimit, "; ", fill, "fill-rule: ", fillRule, "; ", "opacity: ", opacity, ";", filter, visibility ].join("");
},
getSvgFilter: function() {
return this.shadow ? "filter: url(#SVGID_" + this.shadow.id + ");" : "";
},
getSvgId: function() {
return this.id ? 'id="' + this.id + '" ' : "";
},
getSvgTransform: function() {
if (this.group && this.group.type === "path-group") {
return "";
}
var toFixed = fabric.util.toFixed, angle = this.getAngle(), skewX = this.getSkewX() % 360, skewY = this.getSkewY() % 360, center = this.getCenterPoint(), NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, translatePart = this.type === "path-group" ? "" : "translate(" + toFixed(center.x, NUM_FRACTION_DIGITS) + " " + toFixed(center.y, NUM_FRACTION_DIGITS) + ")", anglePart = angle !== 0 ? " rotate(" + toFixed(angle, NUM_FRACTION_DIGITS) + ")" : "", scalePart = this.scaleX === 1 && this.scaleY === 1 ? "" : " scale(" + toFixed(this.scaleX, NUM_FRACTION_DIGITS) + " " + toFixed(this.scaleY, NUM_FRACTION_DIGITS) + ")", skewXPart = skewX !== 0 ? " skewX(" + toFixed(skewX, NUM_FRACTION_DIGITS) + ")" : "", skewYPart = skewY !== 0 ? " skewY(" + toFixed(skewY, NUM_FRACTION_DIGITS) + ")" : "", addTranslateX = this.type === "path-group" ? this.width : 0, flipXPart = this.flipX ? " matrix(-1 0 0 1 " + addTranslateX + " 0) " : "", addTranslateY = this.type === "path-group" ? this.height : 0, flipYPart = this.flipY ? " matrix(1 0 0 -1 0 " + addTranslateY + ")" : "";
return [ translatePart, anglePart, scalePart, flipXPart, flipYPart, skewXPart, skewYPart ].join("");
},
getSvgTransformMatrix: function() {
return this.transformMatrix ? " matrix(" + this.transformMatrix.join(" ") + ") " : "";
},
_createBaseSVGMarkup: function() {
var markup = [];
if (this.fill && this.fill.toLive) {
markup.push(this.fill.toSVG(this, false));
}
if (this.stroke && this.stroke.toLive) {
markup.push(this.stroke.toSVG(this, false));
}
if (this.shadow) {
markup.push(this.shadow.toSVG(this));
}
return markup;
}
});
})();
(function() {
var extend = fabric.util.object.extend;
function saveProps(origin, destination, props) {
var tmpObj = {}, deep = true;
props.forEach(function(prop) {
tmpObj[prop] = origin[prop];
});
extend(origin[destination], tmpObj, deep);
}
function _isEqual(origValue, currentValue) {
if (!fabric.isLikelyNode && origValue instanceof Element) {
return origValue === currentValue;
} else if (origValue instanceof Array) {
if (origValue.length !== currentValue.length) {
return false;
}
var _currentValue = currentValue.concat().sort(), _origValue = origValue.concat().sort();
return !_origValue.some(function(v, i) {
return !_isEqual(_currentValue[i], v);
});
} else if (origValue instanceof Object) {
for (var key in origValue) {
if (!_isEqual(origValue[key], currentValue[key])) {
return false;
}
}
return true;
} else {
return origValue === currentValue;
}
}
fabric.util.object.extend(fabric.Object.prototype, {
hasStateChanged: function() {
return !_isEqual(this.originalState, this);
},
saveState: function(options) {
saveProps(this, "originalState", this.stateProperties);
if (options && options.stateProperties) {
saveProps(this, "originalState", options.stateProperties);
}
return this;
},
setupState: function(options) {
this.originalState = {};
this.saveState(options);
return this;
}
});
})();
(function() {
var deleteIcon = "data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjM2IiB2aWV3Qm94PSIwIDAgMzYgMzYiIHdpZHRoPSIzNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGRlZnM+PGNpcmNsZSBpZD0iYSIgY3g9IjE4IiBjeT0iMTgiIHI9IjEyIi8+PGZpbHRlciBpZD0iYiIgaGVpZ2h0PSIxNTguMyUiIHdpZHRoPSIxNTguMyUiIHg9Ii0yOS4yJSIgeT0iLTIwLjglIj48ZmVPZmZzZXQgZHg9IjAiIGR5PSIyIiBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIi8+PGZlR2F1c3NpYW5CbHVyIGluPSJzaGFkb3dPZmZzZXRPdXRlcjEiIHJlc3VsdD0ic2hhZG93Qmx1ck91dGVyMSIgc3RkRGV2aWF0aW9uPSIyIi8+PGZlQ29sb3JNYXRyaXggaW49InNoYWRvd0JsdXJPdXRlcjEiIHR5cGU9Im1hdHJpeCIgdmFsdWVzPSIwIDAgMCAwIDAgICAwIDAgMCAwIDAgICAwIDAgMCAwIDAgIDAgMCAwIDAuNSAwIi8+PC9maWx0ZXI+PC9kZWZzPjxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCIgdHJhbnNmb3JtPSIiPjx1c2UgZmlsbD0iIzAwMCIgZmlsdGVyPSJ1cmwoI2IpIiB4bGluazpocmVmPSIjYSIvPjx1c2UgZmlsbD0iI2ZmZTYyNiIgZmlsbC1ydWxlPSJldmVub2RkIiB4bGluazpocmVmPSIjYSIvPjxwYXRoIGQ9Im0xOSAxN2g0Yy41NTIyODQ3IDAgMSAuNDQ3NzE1MyAxIDFzLS40NDc3MTUzIDEtMSAxaC00djRjMCAuNTUyMjg0Ny0uNDQ3NzE1MyAxLTEgMXMtMS0uNDQ3NzE1My0xLTF2LTRoLTRjLS41NTIyODQ3IDAtMS0uNDQ3NzE1My0xLTFzLjQ0NzcxNTMtMSAxLTFoNHYtNGMwLS41NTIyODQ3LjQ0NzcxNTMtMSAxLTFzMSAuNDQ3NzE1MyAxIDF6IiBmaWxsPSIjMDAwIiB0cmFuc2Zvcm09Im1hdHJpeCguNzA3MTA2NzggLjcwNzEwNjc4IC0uNzA3MTA2NzggLjcwNzEwNjc4IDE4IC03LjQ1NTg0NCkiLz48L2c+PC9zdmc+";
var resizeIcon = "data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjM2IiB2aWV3Qm94PSIwIDAgMzYgMzYiIHdpZHRoPSIzNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGRlZnM+PGNpcmNsZSBpZD0iYSIgY3g9IjE4IiBjeT0iMTgiIHI9IjEyIi8+PGZpbHRlciBpZD0iYiIgaGVpZ2h0PSIxNTguMyUiIHdpZHRoPSIxNTguMyUiIHg9Ii0yOS4yJSIgeT0iLTIwLjglIj48ZmVPZmZzZXQgZHg9IjAiIGR5PSIyIiBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIi8+PGZlR2F1c3NpYW5CbHVyIGluPSJzaGFkb3dPZmZzZXRPdXRlcjEiIHJlc3VsdD0ic2hhZG93Qmx1ck91dGVyMSIgc3RkRGV2aWF0aW9uPSIyIi8+PGZlQ29sb3JNYXRyaXggaW49InNoYWRvd0JsdXJPdXRlcjEiIHR5cGU9Im1hdHJpeCIgdmFsdWVzPSIwIDAgMCAwIDAgICAwIDAgMCAwIDAgICAwIDAgMCAwIDAgIDAgMCAwIDAuNSAwIi8+PC9maWx0ZXI+PC9kZWZzPjxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCIgdHJhbnNmb3JtPSIiPjx1c2UgZmlsbD0iIzAwMCIgZmlsdGVyPSJ1cmwoI2IpIiB4bGluazpocmVmPSIjYSIvPjx1c2UgZmlsbD0iI2ZmZTYyNiIgZmlsbC1ydWxlPSJldmVub2RkIiB4bGluazpocmVmPSIjYSIvPjxwYXRoIGQ9Im0xNSAyMWgzYy41NTIyODQ3IDAgMSAuNDQ3NzE1MyAxIDFzLS40NDc3MTUzIDEtMSAxaC00Yy0uNTUyMjg0NyAwLTEtLjQ0NzcxNTMtMS0xdi00YzAtLjU1MjI4NDcuNDQ3NzE1My0xIDEtMXMxIC40NDc3MTUzIDEgMXptOC03djRjMCAuNTUyMjg0Ny0uNDQ3NzE1MyAxLTEgMXMtMS0uNDQ3NzE1My0xLTF2LTNoLTNjLS41NTIyODQ3IDAtMS0uNDQ3NzE1My0xLTFzLjQ0NzcxNTMtMSAxLTFoNGMuNTUyMjg0NyAwIDEgLjQ0NzcxNTMgMSAxeiIgZmlsbD0iIzAwMCIvPjwvZz48L3N2Zz4=";
var del = new Image();
del.src = deleteIcon;
var resize = new Image();
resize.src = resizeIcon;
var degreesToRadians = fabric.util.degreesToRadians, isVML = function() {
return typeof G_vmlCanvasManager !== "undefined";
};
fabric.util.object.extend(fabric.Object.prototype, {
_controlsVisibility: null,
_findTargetCorner: function(pointer) {
if (!this.hasControls || !this.active) {
return false;
}
var ex = pointer.x, ey = pointer.y, xPoints, lines;
this.__corner = 0;
for (var i in this.oCoords) {
if (!this.isControlVisible(i)) {
continue;
}
if (i === "mtr" && !this.hasRotatingPoint) {
continue;
}
if (this.get("lockUniScaling") && (i === "mt" || i === "mr" || i === "mb" || i === "ml")) {
continue;
}
lines = this._getImageLines(this.oCoords[i].corner);
xPoints = this._findCrossPoints({
x: ex,
y: ey
}, lines);
if (xPoints !== 0 && xPoints % 2 === 1) {
this.__corner = i;
return i;
}
}
return false;
},
_setCornerCoords: function() {
var coords = this.oCoords, extra = this.cornerStyle === "editor" ? this.cornerSize / 2 : 0, newTheta = degreesToRadians(45 - this.angle), cornerHypotenuse = this.cornerSize * .707106, cosHalfOffset = (cornerHypotenuse + extra) * Math.cos(newTheta), sinHalfOffset = cornerHypotenuse * Math.sin(newTheta), x, y;
for (var point in coords) {
x = coords[point].x;
y = coords[point].y;
coords[point].corner = {
tl: {
x: x - sinHalfOffset,
y: y - cosHalfOffset
},
tr: {
x: x + cosHalfOffset,
y: y - sinHalfOffset
},
bl: {
x: x - cosHalfOffset,
y: y + sinHalfOffset
},
br: {
x: x + sinHalfOffset,
y: y + cosHalfOffset
}
};
}
},
_getNonTransformedDimensions: function() {
var strokeWidth = this.strokeWidth, w = this.width, h = this.height, addStrokeToW = true, addStrokeToH = true;
if (this.type === "line" && this.strokeLineCap === "butt") {
addStrokeToH = w;
addStrokeToW = h;
}
if (addStrokeToH) {
h += h < 0 ? -strokeWidth : strokeWidth;
}
if (addStrokeToW) {
w += w < 0 ? -strokeWidth : strokeWidth;
}
return {
x: w,
y: h
};
},
_getTransformedDimensions: function(skewX, skewY) {
if (typeof skewX === "undefined") {
skewX = this.skewX;
}
if (typeof skewY === "undefined") {
skewY = this.skewY;
}
var dimensions = this._getNonTransformedDimensions(), dimX = dimensions.x / 2, dimY = dimensions.y / 2, points = [ {
x: -dimX,
y: -dimY
}, {
x: dimX,
y: -dimY
}, {
x: -dimX,
y: dimY
}, {
x: dimX,
y: dimY
} ], i, transformMatrix = this._calcDimensionsTransformMatrix(skewX, skewY, false), bbox;
for (i = 0; i < points.length; i++) {
points[i] = fabric.util.transformPoint(points[i], transformMatrix);
}
bbox = fabric.util.makeBoundingBoxFromPoints(points);
return {
x: bbox.width,
y: bbox.height
};
},
_calculateCurrentDimensions: function() {
var vpt = this.getViewportTransform(), dim = this._getTransformedDimensions(), w = dim.x, h = dim.y, p = fabric.util.transformPoint(new fabric.Point(w, h), vpt, true);
return p.scalarAdd(2 * this.padding);
},
drawSelectionBackground: function(ctx) {
if (!this.selectionBackgroundColor || this.group || !this.active) {
return this;
}
ctx.save();
var center = this.getCenterPoint(), wh = this._calculateCurrentDimensions(), vpt = this.canvas.viewportTransform;
ctx.translate(center.x, center.y);
ctx.scale(1 / vpt[0], 1 / vpt[3]);
ctx.rotate(degreesToRadians(this.angle));
ctx.fillStyle = this.selectionBackgroundColor;
ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y);
ctx.restore();
return this;
},
drawBorders: function(ctx) {
if (!this.hasBorders) {
return this;
}
var wh = this._calculateCurrentDimensions(), strokeWidth = 1 / this.borderScaleFactor, width = wh.x + strokeWidth, height = wh.y + strokeWidth;
ctx.save();
ctx.lineWidth = this.borderLineWidth;
ctx.strokeStyle = this.borderColor;
this._setLineDash(ctx, this.borderDashArray, null);
if (this.cornerStyle === "editor") {
var extra = this.cornerSize / 2;
ctx.strokeRect(-width / 2 - extra, -height / 2, width + extra * 2, height);
} else {
ctx.strokeRect(-width / 2, -height / 2, width, height);
}
if (this.hasRotatingPoint && this.isControlVisible("mtr") && !this.get("lockRotation") && this.hasControls) {
var rotateHeight = -height / 2;
ctx.beginPath();
ctx.moveTo(0, rotateHeight);
ctx.lineTo(0, rotateHeight - this.rotatingPointOffset);
ctx.closePath();
ctx.stroke();
}
ctx.restore();
return this;
},
drawBordersInGroup: function(ctx, options) {
if (!this.hasBorders) {
return this;
}
var p = this._getNonTransformedDimensions(), matrix = fabric.util.customTransformMatrix(options.scaleX, options.scaleY, options.skewX), wh = fabric.util.transformPoint(p, matrix), strokeWidth = 1 / this.borderScaleFactor, width = wh.x + strokeWidth + 2 * this.padding, height = wh.y + strokeWidth + 2 * this.padding;
ctx.save();
this._setLineDash(ctx, this.borderDashArray, null);
ctx.strokeStyle = this.borderColor;
ctx.strokeRect(-width / 2, -height / 2, width, height);
ctx.restore();
return this;
},
drawControls: function(ctx) {
if (!this.hasControls) {
return this;
}
var wh = this._calculateCurrentDimensions(), width = wh.x, height = wh.y, scaleOffset = this.cornerSize, left = -(width + scaleOffset) / 2, top = -(height + scaleOffset) / 2, methodName = this.transparentCorners ? "stroke" : "fill";
ctx.save();
ctx.strokeStyle = ctx.fillStyle = this.cornerColor;
if (!this.transparentCorners) {
ctx.strokeStyle = this.cornerStrokeColor;
}
this._setLineDash(ctx, this.cornerDashArray, null);
if (this.cornerStyle === "editor") {
var extra = this.cornerSize / 2;
ctx.drawImage(del, left + width + extra, top, this.cornerSize, this.cornerSize);
ctx.drawImage(resize, left + width + extra, top + height, this.cornerSize, this.cornerSize);
} else if (this.cornerStyle === "cropper") {
var cornerSize = this.cornerSize || 48;
var cornerWidth = this.cornerWidth || 4;
var l = left + cornerSize / 2;
var t = top + cornerSize / 2;
var len = cornerSize;
ctx.strokeStyle = this.cornerColor;
ctx.lineWidth = cornerWidth;
ctx.beginPath();
ctx.moveTo(l, t + len);
ctx.lineTo(l, t);
ctx.lineTo(l + len, t);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(l + width - len, t);
ctx.lineTo(l + width, t);
ctx.lineTo(l + width, t + len);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(l, t + height - len);
ctx.lineTo(l, t + height);
ctx.lineTo(l + len, t + height);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(l + width - len, t + height);
ctx.lineTo(l + width, t + height);
ctx.lineTo(l + width, t + height - len);
ctx.stroke();
} else {
this._drawControl("br", ctx, methodName, left + width, top + height);
this._drawControl("tl", ctx, methodName, left, top);
this._drawControl("tr", ctx, methodName, left + width, top);
this._drawControl("bl", ctx, methodName, left, top + height);
if (!this.get("lockUniScaling")) {
this._drawControl("mt", ctx, methodName, left + width / 2, top);
this._drawControl("mb", ctx, methodName, left + width / 2, top + height);
this._drawControl("mr", ctx, methodName, left + width, top + height / 2);
this._drawControl("ml", ctx, methodName, left, top + height / 2);
}
if (this.hasRotatingPoint) {
var _left = left + width / 2;
var _top = top - this.rotatingPointOffset;
this._drawControl("mtr", ctx, methodName, _left, _top);
}
}
ctx.restore();
return this;
},
_drawControl: function(control, ctx, methodName, left, top) {
if (!this.isControlVisible(control)) {
return;
}
var size = this.cornerSize, stroke = !this.transparentCorners && this.cornerStrokeColor;
switch (this.cornerStyle) {
case "circle":
ctx.beginPath();
ctx.arc(left + size / 2, top + size / 2, size / 2, 0, 2 * Math.PI, false);
ctx[methodName]();
if (stroke) {
ctx.stroke();
}
break;
default:
isVML() || this.transparentCorners || ctx.clearRect(left, top, size, size);
ctx[methodName + "Rect"](left, top, size, size);
if (stroke) {
ctx.strokeRect(left, top, size, size);
}
}
},
isControlVisible: function(controlName) {
return this._getControlsVisibility()[controlName];
},
setControlVisible: function(controlName, visible) {
this._getControlsVisibility()[controlName] = visible;
return this;
},
setControlsVisibility: function(options) {
options || (options = {});
for (var p in options) {
this.setControlVisible(p, options[p]);
}
return this;
},
_getControlsVisibility: function() {
if (!this._controlsVisibility) {
this._controlsVisibility = {
tl: true,
tr: true,
br: true,
bl: true,
ml: true,
mt: true,
mr: true,
mb: true,
mtr: true
};
}
return this._controlsVisibility;
}
});
})();
fabric.util.object.extend(fabric.StaticCanvas.prototype, {
FX_DURATION: 500,
fxCenterObjectH: function(object, callbacks) {
callbacks = callbacks || {};
var empty = function() {}, onComplete = callbacks.onComplete || empty, onChange = callbacks.onChange || empty, _this = this;
fabric.util.animate({
startValue: object.get("left"),
endValue: this.getCenter().left,
duration: this.FX_DURATION,
onChange: function(value) {
object.set("left", value);
_this.renderAll();
onChange();
},
onComplete: function() {
object.setCoords();
onComplete();
}
});
return this;
},
fxCenterObjectV: function(object, callbacks) {
callbacks = callbacks || {};
var empty = function() {}, onComplete = callbacks.onComplete || empty, onChange = callbacks.onChange || empty, _this = this;
fabric.util.animate({
startValue: object.get("top"),
endValue: this.getCenter().top,
duration: this.FX_DURATION,
onChange: function(value) {
object.set("top", value);
_this.renderAll();
onChange();
},
onComplete: function() {
object.setCoords();
onComplete();
}
});
return this;
},
fxRemove: function(object, callbacks) {
callbacks = callbacks || {};
var empty = function() {}, onComplete = callbacks.onComplete || empty, onChange = callbacks.onChange || empty, _this = this;
fabric.util.animate({
startValue: object.get("opacity"),
endValue: 0,
duration: this.FX_DURATION,
onStart: function() {
object.set("active", false);
},
onChange: function(value) {
object.set("opacity", value);
_this.renderAll();
onChange();
},
onComplete: function() {
_this.remove(object);
onComplete();
}
});
return this;
}
});
fabric.util.object.extend(fabric.Object.prototype, {
animate: function() {
if (arguments[0] && typeof arguments[0] === "object") {
var propsToAnimate = [], prop, skipCallbacks;
for (prop in arguments[0]) {
propsToAnimate.push(prop);
}
for (var i = 0, len = propsToAnimate.length; i < len; i++) {
prop = propsToAnimate[i];
skipCallbacks = i !== len - 1;
this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks);
}
} else {
this._animate.apply(this, arguments);
}
return this;
},
_animate: function(property, to, options, skipCallbacks) {
var _this = this, propPair;
to = to.toString();
if (!options) {
options = {};
} else {
options = fabric.util.object.clone(options);
}
if (~property.indexOf(".")) {
propPair = property.split(".");
}
var currentValue = propPair ? this.get(propPair[0])[propPair[1]] : this.get(property);
if (!("from" in options)) {
options.from = currentValue;
}
if (~to.indexOf("=")) {
to = currentValue + parseFloat(to.replace("=", ""));
} else {
to = parseFloat(to);
}
fabric.util.animate({
startValue: options.from,
endValue: to,
byValue: options.by,
easing: options.easing,
duration: options.duration,
abort: options.abort && function() {
return options.abort.call(_this);
},
onChange: function(value) {
if (propPair) {
_this[propPair[0]][propPair[1]] = value;
} else {
_this.set(property, value);
}
if (skipCallbacks) {
return;
}
options.onChange && options.onChange();
},
onComplete: function() {
if (skipCallbacks) {
return;
}
_this.setCoords();
options.onComplete && options.onComplete();
}
});
}
});
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, coordProps = {
x1: 1,
x2: 1,
y1: 1,
y2: 1
}, supportsLineDash = fabric.StaticCanvas.supports("setLineDash");
if (fabric.Line) {
fabric.warn("fabric.Line is already defined");
return;
}
fabric.Line = fabric.util.createClass(fabric.Object, {
type: "line",
x1: 0,
y1: 0,
x2: 0,
y2: 0,
initialize: function(points, options) {
options = options || {};
if (!points) {
points = [ 0, 0, 0, 0 ];
}
this.callSuper("initialize", options);
this.set("x1", points[0]);
this.set("y1", points[1]);
this.set("x2", points[2]);
this.set("y2", points[3]);
this._setWidthHeight(options);
},
_setWidthHeight: function(options) {
options || (options = {});
this.width = Math.abs(this.x2 - this.x1);
this.height = Math.abs(this.y2 - this.y1);
this.left = "left" in options ? options.left : this._getLeftToOriginX();
this.top = "top" in options ? options.top : this._getTopToOriginY();
},
_set: function(key, value) {
this.callSuper("_set", key, value);
if (typeof coordProps[key] !== "undefined") {
this._setWidthHeight();
}
return this;
},
_getLeftToOriginX: makeEdgeToOriginGetter({
origin: "originX",
axis1: "x1",
axis2: "x2",
dimension: "width"
}, {
nearest: "left",
center: "center",
farthest: "right"
}),
_getTopToOriginY: makeEdgeToOriginGetter({
origin: "originY",
axis1: "y1",
axis2: "y2",
dimension: "height"
}, {
nearest: "top",
center: "center",
farthest: "bottom"
}),
_render: function(ctx, noTransform) {
ctx.beginPath();
if (noTransform) {
var cp = this.getCenterPoint();
ctx.translate(cp.x - this.strokeWidth / 2, cp.y - this.strokeWidth / 2);
}
if (!this.strokeDashArray || this.strokeDashArray && supportsLineDash) {
var p = this.calcLinePoints();
ctx.moveTo(p.x1, p.y1);
ctx.lineTo(p.x2, p.y2);
}
ctx.lineWidth = this.strokeWidth;
var origStrokeStyle = ctx.strokeStyle;
ctx.strokeStyle = this.stroke || ctx.fillStyle;
this.stroke && this._renderStroke(ctx);
ctx.strokeStyle = origStrokeStyle;
},
_renderDashedStroke: function(ctx) {
var p = this.calcLinePoints();
ctx.beginPath();
fabric.util.drawDashedLine(ctx, p.x1, p.y1, p.x2, p.y2, this.strokeDashArray);
ctx.closePath();
},
toObject: function(propertiesToInclude) {
return extend(this.callSuper("toObject", propertiesToInclude), this.calcLinePoints());
},
calcLinePoints: function() {
var xMult = this.x1 <= this.x2 ? -1 : 1, yMult = this.y1 <= this.y2 ? -1 : 1, x1 = xMult * this.width * .5, y1 = yMult * this.height * .5, x2 = xMult * this.width * -.5, y2 = yMult * this.height * -.5;
return {
x1: x1,
x2: x2,
y1: y1,
y2: y2
};
},
toSVG: function(reviver) {
var markup = this._createBaseSVGMarkup(), p = {
x1: this.x1,
x2: this.x2,
y1: this.y1,
y2: this.y2
};
if (!(this.group && this.group.type === "path-group")) {
p = this.calcLinePoints();
}
markup.push("<line ", this.getSvgId(), 'x1="', p.x1, '" y1="', p.y1, '" x2="', p.x2, '" y2="', p.y2, '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), this.getSvgTransformMatrix(), '"/>\n');
return reviver ? reviver(markup.join("")) : markup.join("");
},
complexity: function() {
return 1;
}
});
fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" "));
fabric.Line.fromElement = function(element, options) {
var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES), points = [ parsedAttributes.x1 || 0, parsedAttributes.y1 || 0, parsedAttributes.x2 || 0, parsedAttributes.y2 || 0 ];
return new fabric.Line(points, extend(parsedAttributes, options));
};
fabric.Line.fromObject = function(object, callback) {
var points = [ object.x1, object.y1, object.x2, object.y2 ], line = new fabric.Line(points, object);
callback && callback(line);
return line;
};
function makeEdgeToOriginGetter(propertyNames, originValues) {
var origin = propertyNames.origin, axis1 = propertyNames.axis1, axis2 = propertyNames.axis2, dimension = propertyNames.dimension, nearest = originValues.nearest, center = originValues.center, farthest = originValues.farthest;
return function() {
switch (this.get(origin)) {
case nearest:
return Math.min(this.get(axis1), this.get(axis2));
case center:
return Math.min(this.get(axis1), this.get(axis2)) + .5 * this.get(dimension);
case farthest:
return Math.max(this.get(axis1), this.get(axis2));
}
};
}
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), pi = Math.PI, extend = fabric.util.object.extend;
if (fabric.Circle) {
fabric.warn("fabric.Circle is already defined.");
return;
}
fabric.Circle = fabric.util.createClass(fabric.Object, {
type: "circle",
radius: 0,
startAngle: 0,
endAngle: pi * 2,
initialize: function(options) {
options = options || {};
this.callSuper("initialize", options);
this.set("radius", options.radius || 0);
this.startAngle = options.startAngle || this.startAngle;
this.endAngle = options.endAngle || this.endAngle;
},
_set: function(key, value) {
this.callSuper("_set", key, value);
if (key === "radius") {
this.setRadius(value);
}
return this;
},
toObject: function(propertiesToInclude) {
return this.callSuper("toObject", [ "radius", "startAngle", "endAngle" ].concat(propertiesToInclude));
},
toSVG: function(reviver) {
var markup = this._createBaseSVGMarkup(), x = 0, y = 0, angle = (this.endAngle - this.startAngle) % (2 * pi);
if (angle === 0) {
if (this.group && this.group.type === "path-group") {
x = this.left + this.radius;
y = this.top + this.radius;
}
markup.push("<circle ", this.getSvgId(), 'cx="' + x + '" cy="' + y + '" ', 'r="', this.radius, '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), " ", this.getSvgTransformMatrix(), '"/>\n');
} else {
var startX = Math.cos(this.startAngle) * this.radius, startY = Math.sin(this.startAngle) * this.radius, endX = Math.cos(this.endAngle) * this.radius, endY = Math.sin(this.endAngle) * this.radius, largeFlag = angle > pi ? "1" : "0";
markup.push('<path d="M ' + startX + " " + startY, " A " + this.radius + " " + this.radius, " 0 ", +largeFlag + " 1", " " + endX + " " + endY, '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), " ", this.getSvgTransformMatrix(), '"/>\n');
}
return reviver ? reviver(markup.join("")) : markup.join("");
},
_render: function(ctx, noTransform) {
ctx.beginPath();
ctx.arc(noTransform ? this.left + this.radius : 0, noTransform ? this.top + this.radius : 0, this.radius, this.startAngle, this.endAngle, false);
this._renderFill(ctx);
this._renderStroke(ctx);
},
getRadiusX: function() {
return this.get("radius") * this.get("scaleX");
},
getRadiusY: function() {
return this.get("radius") * this.get("scaleY");
},
setRadius: function(value) {
this.radius = value;
return this.set("width", value * 2).set("height", value * 2);
},
complexity: function() {
return 1;
}
});
fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("cx cy r".split(" "));
fabric.Circle.fromElement = function(element, options) {
options || (options = {});
var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES);
if (!isValidRadius(parsedAttributes)) {
throw new Error("value of `r` attribute is required and can not be negative");
}
parsedAttributes.left = parsedAttributes.left || 0;
parsedAttributes.top = parsedAttributes.top || 0;
var obj = new fabric.Circle(extend(parsedAttributes, options));
obj.left -= obj.radius;
obj.top -= obj.radius;
return obj;
};
function isValidRadius(attributes) {
return "radius" in attributes && attributes.radius >= 0;
}
fabric.Circle.fromObject = function(object, callback) {
var circle = new fabric.Circle(object);
callback && callback(circle);
return circle;
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {});
if (fabric.Triangle) {
fabric.warn("fabric.Triangle is already defined");
return;
}
fabric.Triangle = fabric.util.createClass(fabric.Object, {
type: "triangle",
initialize: function(options) {
options = options || {};
this.callSuper("initialize", options);
this.set("width", options.width || 100).set("height", options.height || 100);
},
_render: function(ctx) {
var widthBy2 = this.width / 2, heightBy2 = this.height / 2;
ctx.beginPath();
ctx.moveTo(-widthBy2, heightBy2);
ctx.lineTo(0, -heightBy2);
ctx.lineTo(widthBy2, heightBy2);
ctx.closePath();
this._renderFill(ctx);
this._renderStroke(ctx);
},
_renderDashedStroke: function(ctx) {
var widthBy2 = this.width / 2, heightBy2 = this.height / 2;
ctx.beginPath();
fabric.util.drawDashedLine(ctx, -widthBy2, heightBy2, 0, -heightBy2, this.strokeDashArray);
fabric.util.drawDashedLine(ctx, 0, -heightBy2, widthBy2, heightBy2, this.strokeDashArray);
fabric.util.drawDashedLine(ctx, widthBy2, heightBy2, -widthBy2, heightBy2, this.strokeDashArray);
ctx.closePath();
},
toSVG: function(reviver) {
var markup = this._createBaseSVGMarkup(), widthBy2 = this.width / 2, heightBy2 = this.height / 2, points = [ -widthBy2 + " " + heightBy2, "0 " + -heightBy2, widthBy2 + " " + heightBy2 ].join(",");
markup.push("<polygon ", this.getSvgId(), 'points="', points, '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), '"/>');
return reviver ? reviver(markup.join("")) : markup.join("");
},
complexity: function() {
return 1;
}
});
fabric.Triangle.fromObject = function(object, callback) {
var triangle = new fabric.Triangle(object);
callback && callback(triangle);
return triangle;
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), piBy2 = Math.PI * 2, extend = fabric.util.object.extend;
if (fabric.Ellipse) {
fabric.warn("fabric.Ellipse is already defined.");
return;
}
fabric.Ellipse = fabric.util.createClass(fabric.Object, {
type: "ellipse",
rx: 0,
ry: 0,
initialize: function(options) {
options = options || {};
this.callSuper("initialize", options);
this.set("rx", options.rx || 0);
this.set("ry", options.ry || 0);
},
_set: function(key, value) {
this.callSuper("_set", key, value);
switch (key) {
case "rx":
this.rx = value;
this.set("width", value * 2);
break;
case "ry":
this.ry = value;
this.set("height", value * 2);
break;
}
return this;
},
getRx: function() {
return this.get("rx") * this.get("scaleX");
},
getRy: function() {
return this.get("ry") * this.get("scaleY");
},
toObject: function(propertiesToInclude) {
return this.callSuper("toObject", [ "rx", "ry" ].concat(propertiesToInclude));
},
toSVG: function(reviver) {
var markup = this._createBaseSVGMarkup(), x = 0, y = 0;
if (this.group && this.group.type === "path-group") {
x = this.left + this.rx;
y = this.top + this.ry;
}
markup.push("<ellipse ", this.getSvgId(), 'cx="', x, '" cy="', y, '" ', 'rx="', this.rx, '" ry="', this.ry, '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), this.getSvgTransformMatrix(), '"/>\n');
return reviver ? reviver(markup.join("")) : markup.join("");
},
_render: function(ctx, noTransform) {
ctx.beginPath();
ctx.save();
ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0);
ctx.arc(noTransform ? this.left + this.rx : 0, noTransform ? (this.top + this.ry) * this.rx / this.ry : 0, this.rx, 0, piBy2, false);
ctx.restore();
this._renderFill(ctx);
this._renderStroke(ctx);
},
complexity: function() {
return 1;
}
});
fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" "));
fabric.Ellipse.fromElement = function(element, options) {
options || (options = {});
var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES);
parsedAttributes.left = parsedAttributes.left || 0;
parsedAttributes.top = parsedAttributes.top || 0;
var ellipse = new fabric.Ellipse(extend(parsedAttributes, options));
ellipse.top -= ellipse.ry;
ellipse.left -= ellipse.rx;
return ellipse;
};
fabric.Ellipse.fromObject = function(object, callback) {
var ellipse = new fabric.Ellipse(object);
callback && callback(ellipse);
return ellipse;
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend;
if (fabric.Rect) {
fabric.warn("fabric.Rect is already defined");
return;
}
var stateProperties = fabric.Object.prototype.stateProperties.concat();
stateProperties.push("rx", "ry", "x", "y");
fabric.Rect = fabric.util.createClass(fabric.Object, {
stateProperties: stateProperties,
type: "rect",
rx: 0,
ry: 0,
strokeDashArray: null,
initialize: function(options) {
options = options || {};
this.callSuper("initialize", options);
this._initRxRy();
},
_initRxRy: function() {
if (this.rx && !this.ry) {
this.ry = this.rx;
} else if (this.ry && !this.rx) {
this.rx = this.ry;
}
},
_render: function(ctx, noTransform) {
if (this.width === 1 && this.height === 1) {
ctx.fillRect(-.5, -.5, 1, 1);
return;
}
var rx = this.rx ? Math.min(this.rx, this.width / 2) : 0, ry = this.ry ? Math.min(this.ry, this.height / 2) : 0, w = this.width, h = this.height, x = noTransform ? this.left : -this.width / 2, y = noTransform ? this.top : -this.height / 2, isRounded = rx !== 0 || ry !== 0, k = 1 - .5522847498;
ctx.beginPath();
ctx.moveTo(x + rx, y);
ctx.lineTo(x + w - rx, y);
isRounded && ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry);
ctx.lineTo(x + w, y + h - ry);
isRounded && ctx.bezierCurveTo(x + w, y + h - k * ry, x + w - k * rx, y + h, x + w - rx, y + h);
ctx.lineTo(x + rx, y + h);
isRounded && ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry);
ctx.lineTo(x, y + ry);
isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y);
ctx.closePath();
this._renderFill(ctx);
this._renderStroke(ctx);
},
_renderDashedStroke: function(ctx) {
var x = -this.width / 2, y = -this.height / 2, w = this.width, h = this.height;
ctx.beginPath();
fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray);
fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray);
fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray);
fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray);
ctx.closePath();
},
toObject: function(propertiesToInclude) {
return this.callSuper("toObject", [ "rx", "ry" ].concat(propertiesToInclude));
},
toSVG: function(reviver) {
var markup = this._createBaseSVGMarkup(), x = this.left, y = this.top;
if (!(this.group && this.group.type === "path-group")) {
x = -this.width / 2;
y = -this.height / 2;
}
markup.push("<rect ", this.getSvgId(), 'x="', x, '" y="', y, '" rx="', this.get("rx"), '" ry="', this.get("ry"), '" width="', this.width, '" height="', this.height, '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), this.getSvgTransformMatrix(), '"/>\n');
return reviver ? reviver(markup.join("")) : markup.join("");
},
complexity: function() {
return 1;
}
});
fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" "));
fabric.Rect.fromElement = function(element, options) {
if (!element) {
return null;
}
options = options || {};
var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES);
parsedAttributes.left = parsedAttributes.left || 0;
parsedAttributes.top = parsedAttributes.top || 0;
var rect = new fabric.Rect(extend(options ? fabric.util.object.clone(options) : {}, parsedAttributes));
rect.visible = rect.visible && rect.width > 0 && rect.height > 0;
return rect;
};
fabric.Rect.fromObject = function(object, callback) {
var rect = new fabric.Rect(object);
callback && callback(rect);
return rect;
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {});
if (fabric.Polyline) {
fabric.warn("fabric.Polyline is already defined");
return;
}
fabric.Polyline = fabric.util.createClass(fabric.Object, {
type: "polyline",
points: null,
minX: 0,
minY: 0,
initialize: function(points, options) {
return fabric.Polygon.prototype.initialize.call(this, points, options);
},
_calcDimensions: function() {
return fabric.Polygon.prototype._calcDimensions.call(this);
},
toObject: function(propertiesToInclude) {
return fabric.Polygon.prototype.toObject.call(this, propertiesToInclude);
},
toSVG: function(reviver) {
return fabric.Polygon.prototype.toSVG.call(this, reviver);
},
_render: function(ctx, noTransform) {
if (!fabric.Polygon.prototype.commonRender.call(this, ctx, noTransform)) {
return;
}
this._renderFill(ctx);
this._renderStroke(ctx);
},
_renderDashedStroke: function(ctx) {
var p1, p2;
ctx.beginPath();
for (var i = 0, len = this.points.length; i < len; i++) {
p1 = this.points[i];
p2 = this.points[i + 1] || p1;
fabric.util.drawDashedLine(ctx, p1.x, p1.y, p2.x, p2.y, this.strokeDashArray);
}
},
complexity: function() {
return this.get("points").length;
}
});
fabric.Polyline.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();
fabric.Polyline.fromElement = function(element, options) {
if (!element) {
return null;
}
options || (options = {});
var points = fabric.parsePointsAttribute(element.getAttribute("points")), parsedAttributes = fabric.parseAttributes(element, fabric.Polyline.ATTRIBUTE_NAMES);
return new fabric.Polyline(points, fabric.util.object.extend(parsedAttributes, options));
};
fabric.Polyline.fromObject = function(object, callback) {
var polyline = new fabric.Polyline(object.points, object);
callback && callback(polyline);
return polyline;
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, min = fabric.util.array.min, max = fabric.util.array.max, toFixed = fabric.util.toFixed;
if (fabric.Polygon) {
fabric.warn("fabric.Polygon is already defined");
return;
}
fabric.Polygon = fabric.util.createClass(fabric.Object, {
type: "polygon",
points: null,
minX: 0,
minY: 0,
initialize: function(points, options) {
options = options || {};
this.points = points || [];
this.callSuper("initialize", options);
this._calcDimensions();
if (!("top" in options)) {
this.top = this.minY;
}
if (!("left" in options)) {
this.left = this.minX;
}
this.pathOffset = {
x: this.minX + this.width / 2,
y: this.minY + this.height / 2
};
},
_calcDimensions: function() {
var points = this.points, minX = min(points, "x"), minY = min(points, "y"), maxX = max(points, "x"), maxY = max(points, "y");
this.width = maxX - minX || 0;
this.height = maxY - minY || 0;
this.minX = minX || 0;
this.minY = minY || 0;
},
toObject: function(propertiesToInclude) {
return extend(this.callSuper("toObject", propertiesToInclude), {
points: this.points.concat()
});
},
toSVG: function(reviver) {
var points = [], addTransform, markup = this._createBaseSVGMarkup();
for (var i = 0, len = this.points.length; i < len; i++) {
points.push(toFixed(this.points[i].x, 2), ",", toFixed(this.points[i].y, 2), " ");
}
if (!(this.group && this.group.type === "path-group")) {
addTransform = " translate(" + -this.pathOffset.x + ", " + -this.pathOffset.y + ") ";
}
markup.push("<", this.type, " ", this.getSvgId(), 'points="', points.join(""), '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), addTransform, " ", this.getSvgTransformMatrix(), '"/>\n');
return reviver ? reviver(markup.join("")) : markup.join("");
},
_render: function(ctx, noTransform) {
if (!this.commonRender(ctx, noTransform)) {
return;
}
this._renderFill(ctx);
if (this.stroke || this.strokeDashArray) {
ctx.closePath();
this._renderStroke(ctx);
}
},
commonRender: function(ctx, noTransform) {
var point, len = this.points.length;
if (!len || isNaN(this.points[len - 1].y)) {
return false;
}
noTransform || ctx.translate(-this.pathOffset.x, -this.pathOffset.y);
ctx.beginPath();
ctx.moveTo(this.points[0].x, this.points[0].y);
for (var i = 0; i < len; i++) {
point = this.points[i];
ctx.lineTo(point.x, point.y);
}
return true;
},
_renderDashedStroke: function(ctx) {
fabric.Polyline.prototype._renderDashedStroke.call(this, ctx);
ctx.closePath();
},
complexity: function() {
return this.points.length;
}
});
fabric.Polygon.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();
fabric.Polygon.fromElement = function(element, options) {
if (!element) {
return null;
}
options || (options = {});
var points = fabric.parsePointsAttribute(element.getAttribute("points")), parsedAttributes = fabric.parseAttributes(element, fabric.Polygon.ATTRIBUTE_NAMES);
return new fabric.Polygon(points, extend(parsedAttributes, options));
};
fabric.Polygon.fromObject = function(object, callback) {
var polygon = new fabric.Polygon(object.points, object);
callback && callback(polygon);
return polygon;
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), min = fabric.util.array.min, max = fabric.util.array.max, extend = fabric.util.object.extend, _toString = Object.prototype.toString, drawArc = fabric.util.drawArc, commandLengths = {
m: 2,
l: 2,
h: 1,
v: 1,
c: 6,
s: 4,
q: 4,
t: 2,
a: 7
}, repeatedCommands = {
m: "l",
M: "L"
};
if (fabric.Path) {
fabric.warn("fabric.Path is already defined");
return;
}
fabric.Path = fabric.util.createClass(fabric.Object, {
type: "path",
path: null,
minX: 0,
minY: 0,
initialize: function(path, options) {
options = options || {};
this.setOptions(options);
if (!path) {
path = [];
}
var fromArray = _toString.call(path) === "[object Array]";
this.path = fromArray ? path : path.match && path.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi);
if (!this.path) {
return;
}
if (!fromArray) {
this.path = this._parsePath();
}
this._setPositionDimensions(options);
if (options.sourcePath) {
this.setSourcePath(options.sourcePath);
}
},
_setPositionDimensions: function(options) {
var calcDim = this._parseDimensions();
this.minX = calcDim.left;
this.minY = calcDim.top;
this.width = calcDim.width;
this.height = calcDim.height;
if (typeof options.left === "undefined") {
this.left = calcDim.left + (this.originX === "center" ? this.width / 2 : this.originX === "right" ? this.width : 0);
}
if (typeof options.top === "undefined") {
this.top = calcDim.top + (this.originY === "center" ? this.height / 2 : this.originY === "bottom" ? this.height : 0);
}
this.pathOffset = this.pathOffset || {
x: this.minX + this.width / 2,
y: this.minY + this.height / 2
};
},
_renderPathCommands: function(ctx) {
var current, previous = null, subpathStartX = 0, subpathStartY = 0, x = 0, y = 0, controlX = 0, controlY = 0, tempX, tempY, l = -this.pathOffset.x, t = -this.pathOffset.y;
if (this.group && this.group.type === "path-group") {
l = 0;
t = 0;
}
ctx.beginPath();
for (var i = 0, len = this.path.length; i < len; ++i) {
current = this.path[i];
switch (current[0]) {
case "l":
x += current[1];
y += current[2];
ctx.lineTo(x + l, y + t);
break;
case "L":
x = current[1];
y = current[2];
ctx.lineTo(x + l, y + t);
break;
case "h":
x += current[1];
ctx.lineTo(x + l, y + t);
break;
case "H":
x = current[1];
ctx.lineTo(x + l, y + t);
break;
case "v":
y += current[1];
ctx.lineTo(x + l, y + t);
break;
case "V":
y = current[1];
ctx.lineTo(x + l, y + t);
break;
case "m":
x += current[1];
y += current[2];
subpathStartX = x;
subpathStartY = y;
ctx.moveTo(x + l, y + t);
break;
case "M":
x = current[1];
y = current[2];
subpathStartX = x;
subpathStartY = y;
ctx.moveTo(x + l, y + t);
break;
case "c":
tempX = x + current[5];
tempY = y + current[6];
controlX = x + current[3];
controlY = y + current[4];
ctx.bezierCurveTo(x + current[1] + l, y + current[2] + t, controlX + l, controlY + t, tempX + l, tempY + t);
x = tempX;
y = tempY;
break;
case "C":
x = current[5];
y = current[6];
controlX = current[3];
controlY = current[4];
ctx.bezierCurveTo(current[1] + l, current[2] + t, controlX + l, controlY + t, x + l, y + t);
break;
case "s":
tempX = x + current[3];
tempY = y + current[4];
if (previous[0].match(/[CcSs]/) === null) {
controlX = x;
controlY = y;
} else {
controlX = 2 * x - controlX;
controlY = 2 * y - controlY;
}
ctx.bezierCurveTo(controlX + l, controlY + t, x + current[1] + l, y + current[2] + t, tempX + l, tempY + t);
controlX = x + current[1];
controlY = y + current[2];
x = tempX;
y = tempY;
break;
case "S":
tempX = current[3];
tempY = current[4];
if (previous[0].match(/[CcSs]/) === null) {
controlX = x;
controlY = y;
} else {
controlX = 2 * x - controlX;
controlY = 2 * y - controlY;
}
ctx.bezierCurveTo(controlX + l, controlY + t, current[1] + l, current[2] + t, tempX + l, tempY + t);
x = tempX;
y = tempY;
controlX = current[1];
controlY = current[2];
break;
case "q":
tempX = x + current[3];
tempY = y + current[4];
controlX = x + current[1];
controlY = y + current[2];
ctx.quadraticCurveTo(controlX + l, controlY + t, tempX + l, tempY + t);
x = tempX;
y = tempY;
break;
case "Q":
tempX = current[3];
tempY = current[4];
ctx.quadraticCurveTo(current[1] + l, current[2] + t, tempX + l, tempY + t);
x = tempX;
y = tempY;
controlX = current[1];
controlY = current[2];
break;
case "t":
tempX = x + current[1];
tempY = y + current[2];
if (previous[0].match(/[QqTt]/) === null) {
controlX = x;
controlY = y;
} else {
controlX = 2 * x - controlX;
controlY = 2 * y - controlY;
}
ctx.quadraticCurveTo(controlX + l, controlY + t, tempX + l, tempY + t);
x = tempX;
y = tempY;
break;
case "T":
tempX = current[1];
tempY = current[2];
if (previous[0].match(/[QqTt]/) === null) {
controlX = x;
controlY = y;
} else {
controlX = 2 * x - controlX;
controlY = 2 * y - controlY;
}
ctx.quadraticCurveTo(controlX + l, controlY + t, tempX + l, tempY + t);
x = tempX;
y = tempY;
break;
case "a":
drawArc(ctx, x + l, y + t, [ current[1], current[2], current[3], current[4], current[5], current[6] + x + l, current[7] + y + t ]);
x += current[6];
y += current[7];
break;
case "A":
drawArc(ctx, x + l, y + t, [ current[1], current[2], current[3], current[4], current[5], current[6] + l, current[7] + t ]);
x = current[6];
y = current[7];
break;
case "z":
case "Z":
x = subpathStartX;
y = subpathStartY;
ctx.closePath();
break;
}
previous = current;
}
},
_render: function(ctx) {
this._renderPathCommands(ctx);
this._renderFill(ctx);
this._renderStroke(ctx);
},
toString: function() {
return "#<fabric.Path (" + this.complexity() + '): { "top": ' + this.top + ', "left": ' + this.left + " }>";
},
toObject: function(propertiesToInclude) {
var o = extend(this.callSuper("toObject", [ "sourcePath", "pathOffset" ].concat(propertiesToInclude)), {
path: this.path.map(function(item) {
return item.slice();
})
});
return o;
},
toDatalessObject: function(propertiesToInclude) {
var o = this.toObject(propertiesToInclude);
if (this.sourcePath) {
o.path = this.sourcePath;
}
delete o.sourcePath;
return o;
},
toSVG: function(reviver) {
var chunks = [], markup = this._createBaseSVGMarkup(), addTransform = "";
for (var i = 0, len = this.path.length; i < len; i++) {
chunks.push(this.path[i].join(" "));
}
var path = chunks.join(" ");
if (!(this.group && this.group.type === "path-group")) {
addTransform = " translate(" + -this.pathOffset.x + ", " + -this.pathOffset.y + ") ";
}
markup.push("<path ", this.getSvgId(), 'd="', path, '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), addTransform, this.getSvgTransformMatrix(), '" stroke-linecap="round" ', "/>\n");
return reviver ? reviver(markup.join("")) : markup.join("");
},
complexity: function() {
return this.path.length;
},
_parsePath: function() {
var result = [], coords = [], currentPath, parsed, re = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi, match, coordsStr;
for (var i = 0, coordsParsed, len = this.path.length; i < len; i++) {
currentPath = this.path[i];
coordsStr = currentPath.slice(1).trim();
coords.length = 0;
while (match = re.exec(coordsStr)) {
coords.push(match[0]);
}
coordsParsed = [ currentPath.charAt(0) ];
for (var j = 0, jlen = coords.length; j < jlen; j++) {
parsed = parseFloat(coords[j]);
if (!isNaN(parsed)) {
coordsParsed.push(parsed);
}
}
var command = coordsParsed[0], commandLength = commandLengths[command.toLowerCase()], repeatedCommand = repeatedCommands[command] || command;
if (coordsParsed.length - 1 > commandLength) {
for (var k = 1, klen = coordsParsed.length; k < klen; k += commandLength) {
result.push([ command ].concat(coordsParsed.slice(k, k + commandLength)));
command = repeatedCommand;
}
} else {
result.push(coordsParsed);
}
}
return result;
},
_parseDimensions: function() {
var aX = [], aY = [], current, previous = null, subpathStartX = 0, subpathStartY = 0, x = 0, y = 0, controlX = 0, controlY = 0, tempX, tempY, bounds;
for (var i = 0, len = this.path.length; i < len; ++i) {
current = this.path[i];
switch (current[0]) {
case "l":
x += current[1];
y += current[2];
bounds = [];
break;
case "L":
x = current[1];
y = current[2];
bounds = [];
break;
case "h":
x += current[1];
bounds = [];
break;
case "H":
x = current[1];
bounds = [];
break;
case "v":
y += current[1];
bounds = [];
break;
case "V":
y = current[1];
bounds = [];
break;
case "m":
x += current[1];
y += current[2];
subpathStartX = x;
subpathStartY = y;
bounds = [];
break;
case "M":
x = current[1];
y = current[2];
subpathStartX = x;
subpathStartY = y;
bounds = [];
break;
case "c":
tempX = x + current[5];
tempY = y + current[6];
controlX = x + current[3];
controlY = y + current[4];
bounds = fabric.util.getBoundsOfCurve(x, y, x + current[1], y + current[2], controlX, controlY, tempX, tempY);
x = tempX;
y = tempY;
break;
case "C":
x = current[5];
y = current[6];
controlX = current[3];
controlY = current[4];
bounds = fabric.util.getBoundsOfCurve(x, y, current[1], current[2], controlX, controlY, x, y);
break;
case "s":
tempX = x + current[3];
tempY = y + current[4];
if (previous[0].match(/[CcSs]/) === null) {
controlX = x;
controlY = y;
} else {
controlX = 2 * x - controlX;
controlY = 2 * y - controlY;
}
bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, x + current[1], y + current[2], tempX, tempY);
controlX = x + current[1];
controlY = y + current[2];
x = tempX;
y = tempY;
break;
case "S":
tempX = current[3];
tempY = current[4];
if (previous[0].match(/[CcSs]/) === null) {
controlX = x;
controlY = y;
} else {
controlX = 2 * x - controlX;
controlY = 2 * y - controlY;
}
bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, current[1], current[2], tempX, tempY);
x = tempX;
y = tempY;
controlX = current[1];
controlY = current[2];
break;
case "q":
tempX = x + current[3];
tempY = y + current[4];
controlX = x + current[1];
controlY = y + current[2];
bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, controlX, controlY, tempX, tempY);
x = tempX;
y = tempY;
break;
case "Q":
controlX = current[1];
controlY = current[2];
bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, controlX, controlY, current[3], current[4]);
x = current[3];
y = current[4];
break;
case "t":
tempX = x + current[1];
tempY = y + current[2];
if (previous[0].match(/[QqTt]/) === null) {
controlX = x;
controlY = y;
} else {
controlX = 2 * x - controlX;
controlY = 2 * y - controlY;
}
bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, controlX, controlY, tempX, tempY);
x = tempX;
y = tempY;
break;
case "T":
tempX = current[1];
tempY = current[2];
if (previous[0].match(/[QqTt]/) === null) {
controlX = x;
controlY = y;
} else {
controlX = 2 * x - controlX;
controlY = 2 * y - controlY;
}
bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, controlX, controlY, tempX, tempY);
x = tempX;
y = tempY;
break;
case "a":
bounds = fabric.util.getBoundsOfArc(x, y, current[1], current[2], current[3], current[4], current[5], current[6] + x, current[7] + y);
x += current[6];
y += current[7];
break;
case "A":
bounds = fabric.util.getBoundsOfArc(x, y, current[1], current[2], current[3], current[4], current[5], current[6], current[7]);
x = current[6];
y = current[7];
break;
case "z":
case "Z":
x = subpathStartX;
y = subpathStartY;
break;
}
previous = current;
bounds.forEach(function(point) {
aX.push(point.x);
aY.push(point.y);
});
aX.push(x);
aY.push(y);
}
var minX = min(aX) || 0, minY = min(aY) || 0, maxX = max(aX) || 0, maxY = max(aY) || 0, deltaX = maxX - minX, deltaY = maxY - minY, o = {
left: minX,
top: minY,
width: deltaX,
height: deltaY
};
return o;
}
});
fabric.Path.fromObject = function(object, callback) {
var path;
if (typeof object.path === "string") {
fabric.loadSVGFromURL(object.path, function(elements) {
var pathUrl = object.path;
path = elements[0];
delete object.path;
fabric.util.object.extend(path, object);
path.setSourcePath(pathUrl);
callback && callback(path);
});
} else {
path = new fabric.Path(object.path, object);
callback && callback(path);
return path;
}
};
fabric.Path.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat([ "d" ]);
fabric.Path.fromElement = function(element, callback, options) {
var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES);
callback && callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options)));
};
fabric.Path.async = true;
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, invoke = fabric.util.array.invoke, parentToObject = fabric.Object.prototype.toObject;
if (fabric.PathGroup) {
fabric.warn("fabric.PathGroup is already defined");
return;
}
fabric.PathGroup = fabric.util.createClass(fabric.Path, {
type: "path-group",
fill: "",
initialize: function(paths, options) {
options = options || {};
this.paths = paths || [];
for (var i = this.paths.length; i--; ) {
this.paths[i].group = this;
}
if (options.toBeParsed) {
this.parseDimensionsFromPaths(options);
delete options.toBeParsed;
}
this.setOptions(options);
this.setCoords();
if (options.sourcePath) {
this.setSourcePath(options.sourcePath);
}
},
parseDimensionsFromPaths: function(options) {
var points, p, xC = [], yC = [], path, height, width, m;
for (var j = this.paths.length; j--; ) {
path = this.paths[j];
height = path.height + path.strokeWidth;
width = path.width + path.strokeWidth;
points = [ {
x: path.left,
y: path.top
}, {
x: path.left + width,
y: path.top
}, {
x: path.left,
y: path.top + height
}, {
x: path.left + width,
y: path.top + height
} ];
m = this.paths[j].transformMatrix;
for (var i = 0; i < points.length; i++) {
p = points[i];
if (m) {
p = fabric.util.transformPoint(p, m, false);
}
xC.push(p.x);
yC.push(p.y);
}
}
options.width = Math.max.apply(null, xC);
options.height = Math.max.apply(null, yC);
},
render: function(ctx) {
if (!this.visible) {
return;
}
ctx.save();
if (this.transformMatrix) {
ctx.transform.apply(ctx, this.transformMatrix);
}
this.transform(ctx);
this._setShadow(ctx);
this.clipTo && fabric.util.clipContext(this, ctx);
ctx.translate(-this.width / 2, -this.height / 2);
for (var i = 0, l = this.paths.length; i < l; ++i) {
this.paths[i].render(ctx, true);
}
this.clipTo && ctx.restore();
ctx.restore();
},
_set: function(prop, value) {
if (prop === "fill" && value && this.isSameColor()) {
var i = this.paths.length;
while (i--) {
this.paths[i]._set(prop, value);
}
}
return this.callSuper("_set", prop, value);
},
toObject: function(propertiesToInclude) {
var o = extend(parentToObject.call(this, [ "sourcePath" ].concat(propertiesToInclude)), {
paths: invoke(this.getObjects(), "toObject", propertiesToInclude)
});
return o;
},
toDatalessObject: function(propertiesToInclude) {
var o = this.toObject(propertiesToInclude);
if (this.sourcePath) {
o.paths = this.sourcePath;
}
return o;
},
toSVG: function(reviver) {
var objects = this.getObjects(), p = this.getPointByOrigin("left", "top"), translatePart = "translate(" + p.x + " " + p.y + ")", markup = this._createBaseSVGMarkup();
markup.push("<g ", this.getSvgId(), 'style="', this.getSvgStyles(), '" ', 'transform="', this.getSvgTransformMatrix(), translatePart, this.getSvgTransform(), '" ', ">\n");
for (var i = 0, len = objects.length; i < len; i++) {
markup.push("\t", objects[i].toSVG(reviver));
}
markup.push("</g>\n");
return reviver ? reviver(markup.join("")) : markup.join("");
},
toString: function() {
return "#<fabric.PathGroup (" + this.complexity() + "): { top: " + this.top + ", left: " + this.left + " }>";
},
isSameColor: function() {
var firstPathFill = this.getObjects()[0].get("fill") || "";
if (typeof firstPathFill !== "string") {
return false;
}
firstPathFill = firstPathFill.toLowerCase();
return this.getObjects().every(function(path) {
var pathFill = path.get("fill") || "";
return typeof pathFill === "string" && pathFill.toLowerCase() === firstPathFill;
});
},
complexity: function() {
return this.paths.reduce(function(total, path) {
return total + (path && path.complexity ? path.complexity() : 0);
}, 0);
},
getObjects: function() {
return this.paths;
}
});
fabric.PathGroup.fromObject = function(object, callback) {
if (typeof object.paths === "string") {
fabric.loadSVGFromURL(object.paths, function(elements) {
var pathUrl = object.paths;
delete object.paths;
var pathGroup = fabric.util.groupSVGElements(elements, object, pathUrl);
callback(pathGroup);
});
} else {
fabric.util.enlivenObjects(object.paths, function(enlivenedObjects) {
delete object.paths;
callback(new fabric.PathGroup(enlivenedObjects, object));
});
}
};
fabric.PathGroup.async = true;
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, min = fabric.util.array.min, max = fabric.util.array.max, invoke = fabric.util.array.invoke;
if (fabric.Group) {
return;
}
var _lockProperties = {
lockMovementX: true,
lockMovementY: true,
lockRotation: true,
lockScalingX: true,
lockScalingY: true,
lockUniScaling: true
};
fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection, {
type: "group",
strokeWidth: 0,
subTargetCheck: false,
initialize: function(objects, options, isAlreadyGrouped) {
options = options || {};
this._objects = [];
isAlreadyGrouped && this.callSuper("initialize", options);
this._objects = objects || [];
for (var i = this._objects.length; i--; ) {
this._objects[i].group = this;
}
this.originalState = {};
if (options.originX) {
this.originX = options.originX;
}
if (options.originY) {
this.originY = options.originY;
}
if (isAlreadyGrouped) {
this._updateObjectsCoords(true);
} else {
this._calcBounds();
this._updateObjectsCoords();
this.callSuper("initialize", options);
}
this.setCoords();
this.saveCoords();
},
_updateObjectsCoords: function(skipCoordsChange) {
for (var i = this._objects.length; i--; ) {
this._updateObjectCoords(this._objects[i], skipCoordsChange);
}
},
_updateObjectCoords: function(object, skipCoordsChange) {
object.__origHasControls = object.hasControls;
object.hasControls = false;
if (skipCoordsChange) {
return;
}
var objectLeft = object.getLeft(), objectTop = object.getTop(), center = this.getCenterPoint();
object.set({
originalLeft: objectLeft,
originalTop: objectTop,
left: objectLeft - center.x,
top: objectTop - center.y
});
object.setCoords();
},
toString: function() {
return "#<fabric.Group: (" + this.complexity() + ")>";
},
addWithUpdate: function(object) {
this._restoreObjectsState();
fabric.util.resetObjectTransform(this);
if (object) {
this._objects.push(object);
object.group = this;
object._set("canvas", this.canvas);
}
this.forEachObject(this._setObjectActive, this);
this._calcBounds();
this._updateObjectsCoords();
return this;
},
_setObjectActive: function(object) {
object.set("active", true);
object.group = this;
},
removeWithUpdate: function(object) {
this._restoreObjectsState();
fabric.util.resetObjectTransform(this);
this.forEachObject(this._setObjectActive, this);
this.remove(object);
this._calcBounds();
this._updateObjectsCoords();
return this;
},
_onObjectAdded: function(object) {
object.group = this;
object._set("canvas", this.canvas);
},
_onObjectRemoved: function(object) {
delete object.group;
object.set("active", false);
},
delegatedProperties: {
fill: true,
stroke: true,
strokeWidth: true,
fontFamily: true,
fontWeight: true,
fontSize: true,
fontStyle: true,
lineHeight: true,
textDecoration: true,
textAlign: true,
backgroundColor: true
},
_set: function(key, value) {
var i = this._objects.length;
if (this.delegatedProperties[key] || key === "canvas") {
while (i--) {
this._objects[i].set(key, value);
}
} else {
while (i--) {
this._objects[i].setOnGroup(key, value);
}
}
this.callSuper("_set", key, value);
},
toObject: function(propertiesToInclude) {
return extend(this.callSuper("toObject", propertiesToInclude), {
objects: invoke(this._objects, "toObject", propertiesToInclude)
});
},
render: function(ctx) {
if (!this.visible) {
return;
}
ctx.save();
if (this.transformMatrix) {
ctx.transform.apply(ctx, this.transformMatrix);
}
this.transform(ctx);
this._setShadow(ctx);
this.clipTo && fabric.util.clipContext(this, ctx);
this._transformDone = true;
for (var i = 0, len = this._objects.length; i < len; i++) {
this._renderObject(this._objects[i], ctx);
}
this.clipTo && ctx.restore();
ctx.restore();
this._transformDone = false;
},
_renderControls: function(ctx, noTransform) {
this.callSuper("_renderControls", ctx, noTransform);
for (var i = 0, len = this._objects.length; i < len; i++) {
this._objects[i]._renderControls(ctx);
}
},
_renderObject: function(object, ctx) {
if (!object.visible) {
return;
}
var originalHasRotatingPoint = object.hasRotatingPoint;
object.hasRotatingPoint = false;
object.render(ctx);
object.hasRotatingPoint = originalHasRotatingPoint;
},
_restoreObjectsState: function() {
this._objects.forEach(this._restoreObjectState, this);
return this;
},
realizeTransform: function(object) {
var matrix = object.calcTransformMatrix(), options = fabric.util.qrDecompose(matrix), center = new fabric.Point(options.translateX, options.translateY);
object.scaleX = options.scaleX;
object.scaleY = options.scaleY;
object.skewX = options.skewX;
object.skewY = options.skewY;
object.angle = options.angle;
object.flipX = false;
object.flipY = false;
object.setPositionByOrigin(center, "center", "center");
return object;
},
_restoreObjectState: function(object) {
this.realizeTransform(object);
object.setCoords();
object.hasControls = object.__origHasControls;
delete object.__origHasControls;
object.set("active", false);
delete object.group;
return this;
},
destroy: function() {
return this._restoreObjectsState();
},
saveCoords: function() {
this._originalLeft = this.get("left");
this._originalTop = this.get("top");
return this;
},
hasMoved: function() {
return this._originalLeft !== this.get("left") || this._originalTop !== this.get("top");
},
setObjectsCoords: function() {
this.forEachObject(function(object) {
object.setCoords();
});
return this;
},
_calcBounds: function(onlyWidthHeight) {
var aX = [], aY = [], o, prop, props = [ "tr", "br", "bl", "tl" ], i = 0, iLen = this._objects.length, j, jLen = props.length;
for (;i < iLen; ++i) {
o = this._objects[i];
o.setCoords();
for (j = 0; j < jLen; j++) {
prop = props[j];
aX.push(o.oCoords[prop].x);
aY.push(o.oCoords[prop].y);
}
}
this.set(this._getBounds(aX, aY, onlyWidthHeight));
},
_getBounds: function(aX, aY, onlyWidthHeight) {
var ivt = fabric.util.invertTransform(this.getViewportTransform()), minXY = fabric.util.transformPoint(new fabric.Point(min(aX), min(aY)), ivt), maxXY = fabric.util.transformPoint(new fabric.Point(max(aX), max(aY)), ivt), obj = {
width: maxXY.x - minXY.x || 0,
height: maxXY.y - minXY.y || 0
};
if (!onlyWidthHeight) {
obj.left = minXY.x || 0;
obj.top = minXY.y || 0;
if (this.originX === "center") {
obj.left += obj.width / 2;
}
if (this.originX === "right") {
obj.left += obj.width;
}
if (this.originY === "center") {
obj.top += obj.height / 2;
}
if (this.originY === "bottom") {
obj.top += obj.height;
}
}
return obj;
},
toSVG: function(reviver) {
var markup = this._createBaseSVGMarkup();
markup.push("<g ", this.getSvgId(), 'transform="', this.getSvgTransform(), this.getSvgTransformMatrix(), '" style="', this.getSvgFilter(), '">\n');
for (var i = 0, len = this._objects.length; i < len; i++) {
markup.push("\t", this._objects[i].toSVG(reviver));
}
markup.push("</g>\n");
return reviver ? reviver(markup.join("")) : markup.join("");
},
get: function(prop) {
if (prop in _lockProperties) {
if (this[prop]) {
return this[prop];
} else {
for (var i = 0, len = this._objects.length; i < len; i++) {
if (this._objects[i][prop]) {
return true;
}
}
return false;
}
} else {
if (prop in this.delegatedProperties) {
return this._objects[0] && this._objects[0].get(prop);
}
return this[prop];
}
}
});
fabric.Group.fromObject = function(object, callback) {
fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) {
delete object.objects;
callback && callback(new fabric.Group(enlivenedObjects, object, true));
});
};
fabric.Group.async = true;
})( true ? exports : this);
(function(global) {
"use strict";
var extend = fabric.util.object.extend;
if (!global.fabric) {
global.fabric = {};
}
if (global.fabric.Image) {
fabric.warn("fabric.Image is already defined.");
return;
}
var stateProperties = fabric.Object.prototype.stateProperties.concat();
stateProperties.push("alignX", "alignY", "meetOrSlice");
fabric.Image = fabric.util.createClass(fabric.Object, {
type: "image",
crossOrigin: "",
alignX: "none",
alignY: "none",
meetOrSlice: "meet",
strokeWidth: 0,
_lastScaleX: 1,
_lastScaleY: 1,
minimumScaleTrigger: .5,
stateProperties: stateProperties,
initialize: function(element, options, callback) {
options || (options = {});
this.filters = [];
this.resizeFilters = [];
this.callSuper("initialize", options);
this._initElement(element, options, callback);
},
getElement: function() {
return this._element;
},
setElement: function(element, callback, options) {
var _callback, _this;
this._element = element;
this._originalElement = element;
this._initConfig(options);
if (this.resizeFilters.length === 0) {
_callback = callback;
} else {
_this = this;
_callback = function() {
_this.applyFilters(callback, _this.resizeFilters, _this._filteredEl || _this._originalElement, true);
};
}
if (this.filters.length !== 0) {
this.applyFilters(_callback);
} else if (_callback) {
_callback(this);
}
return this;
},
setCrossOrigin: function(value) {
this.crossOrigin = value;
this._element.crossOrigin = value;
return this;
},
getOriginalSize: function() {
var element = this.getElement();
return {
width: element.width,
height: element.height
};
},
_stroke: function(ctx) {
if (!this.stroke || this.strokeWidth === 0) {
return;
}
var w = this.width / 2, h = this.height / 2;
ctx.beginPath();
ctx.moveTo(-w, -h);
ctx.lineTo(w, -h);
ctx.lineTo(w, h);
ctx.lineTo(-w, h);
ctx.lineTo(-w, -h);
ctx.closePath();
},
_renderDashedStroke: function(ctx) {
var x = -this.width / 2, y = -this.height / 2, w = this.width, h = this.height;
ctx.save();
this._setStrokeStyles(ctx);
ctx.beginPath();
fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray);
fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray);
fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray);
fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray);
ctx.closePath();
ctx.restore();
},
toObject: function(propertiesToInclude) {
var filters = [], resizeFilters = [], scaleX = 1, scaleY = 1;
this.filters.forEach(function(filterObj) {
if (filterObj) {
if (filterObj.type === "Resize") {
scaleX *= filterObj.scaleX;
scaleY *= filterObj.scaleY;
}
filters.push(filterObj.toObject());
}
});
this.resizeFilters.forEach(function(filterObj) {
filterObj && resizeFilters.push(filterObj.toObject());
});
var object = extend(this.callSuper("toObject", [ "crossOrigin", "alignX", "alignY", "meetOrSlice" ].concat(propertiesToInclude)), {
src: this.getSrc(),
filters: filters,
resizeFilters: resizeFilters
});
object.width /= scaleX;
object.height /= scaleY;
return object;
},
toSVG: function(reviver) {
var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2, preserveAspectRatio = "none", filtered = true;
if (this.group && this.group.type === "path-group") {
x = this.left;
y = this.top;
}
if (this.alignX !== "none" && this.alignY !== "none") {
preserveAspectRatio = "x" + this.alignX + "Y" + this.alignY + " " + this.meetOrSlice;
}
markup.push('<g transform="', this.getSvgTransform(), this.getSvgTransformMatrix(), '">\n', "<image ", this.getSvgId(), 'xlink:href="', this.getSvgSrc(filtered), '" x="', x, '" y="', y, '" style="', this.getSvgStyles(), '" width="', this.width, '" height="', this.height, '" preserveAspectRatio="', preserveAspectRatio, '"', "></image>\n");
if (this.stroke || this.strokeDashArray) {
var origFill = this.fill;
this.fill = null;
markup.push("<rect ", 'x="', x, '" y="', y, '" width="', this.width, '" height="', this.height, '" style="', this.getSvgStyles(), '"/>\n');
this.fill = origFill;
}
markup.push("</g>\n");
return reviver ? reviver(markup.join("")) : markup.join("");
},
getSrc: function(filtered) {
var element = filtered ? this._element : this._originalElement;
if (element) {
return fabric.isLikelyNode ? element._src : element.src;
} else {
return this.src || "";
}
},
setSrc: function(src, callback, options) {
fabric.util.loadImage(src, function(img) {
return this.setElement(img, callback, options);
}, this, options && options.crossOrigin);
},
toString: function() {
return '#<fabric.Image: { src: "' + this.getSrc() + '" }>';
},
applyFilters: function(callback, filters, imgElement, forResizing) {
filters = filters || this.filters;
imgElement = imgElement || this._originalElement;
if (!imgElement) {
return;
}
var replacement = fabric.util.createImage(), retinaScaling = this.canvas ? this.canvas.getRetinaScaling() : fabric.devicePixelRatio, minimumScale = this.minimumScaleTrigger / retinaScaling, _this = this, scaleX, scaleY;
if (filters.length === 0) {
this._element = imgElement;
callback && callback(this);
return imgElement;
}
var canvasEl = fabric.util.createCanvasElement();
canvasEl.width = imgElement.width;
canvasEl.height = imgElement.height;
canvasEl.getContext("2d").drawImage(imgElement, 0, 0, imgElement.width, imgElement.height);
filters.forEach(function(filter) {
if (!filter) {
return;
}
if (forResizing) {
scaleX = _this.scaleX < minimumScale ? _this.scaleX : 1;
scaleY = _this.scaleY < minimumScale ? _this.scaleY : 1;
if (scaleX * retinaScaling < 1) {
scaleX *= retinaScaling;
}
if (scaleY * retinaScaling < 1) {
scaleY *= retinaScaling;
}
} else {
scaleX = filter.scaleX;
scaleY = filter.scaleY;
}
filter.applyTo(canvasEl, scaleX, scaleY);
if (!forResizing && filter.type === "Resize") {
_this.width *= filter.scaleX;
_this.height *= filter.scaleY;
}
});
replacement.width = canvasEl.width;
replacement.height = canvasEl.height;
if (fabric.isLikelyNode) {
replacement.src = canvasEl.toBuffer(undefined, fabric.Image.pngCompression);
_this._element = replacement;
!forResizing && (_this._filteredEl = replacement);
callback && callback(_this);
} else {
replacement.onload = function() {
_this._element = replacement;
!forResizing && (_this._filteredEl = replacement);
callback && callback(_this);
replacement.onload = canvasEl = null;
};
replacement.src = canvasEl.toDataURL("image/png");
}
return canvasEl;
},
_render: function(ctx, noTransform) {
var x, y, imageMargins = this._findMargins(), elementToDraw;
x = noTransform ? this.left : -this.width / 2;
y = noTransform ? this.top : -this.height / 2;
if (this.meetOrSlice === "slice") {
ctx.beginPath();
ctx.rect(x, y, this.width, this.height);
ctx.clip();
}
if (this.isMoving === false && this.resizeFilters.length && this._needsResize()) {
this._lastScaleX = this.scaleX;
this._lastScaleY = this.scaleY;
elementToDraw = this.applyFilters(null, this.resizeFilters, this._filteredEl || this._originalElement, true);
} else {
elementToDraw = this._element;
}
elementToDraw && ctx.drawImage(elementToDraw, x + imageMargins.marginX, y + imageMargins.marginY, imageMargins.width, imageMargins.height);
this._stroke(ctx);
this._renderStroke(ctx);
},
_needsResize: function() {
return this.scaleX !== this._lastScaleX || this.scaleY !== this._lastScaleY;
},
_findMargins: function() {
var width = this.width, height = this.height, scales, scale, marginX = 0, marginY = 0;
if (this.alignX !== "none" || this.alignY !== "none") {
scales = [ this.width / this._element.width, this.height / this._element.height ];
scale = this.meetOrSlice === "meet" ? Math.min.apply(null, scales) : Math.max.apply(null, scales);
width = this._element.width * scale;
height = this._element.height * scale;
if (this.alignX === "Mid") {
marginX = (this.width - width) / 2;
}
if (this.alignX === "Max") {
marginX = this.width - width;
}
if (this.alignY === "Mid") {
marginY = (this.height - height) / 2;
}
if (this.alignY === "Max") {
marginY = this.height - height;
}
}
return {
width: width,
height: height,
marginX: marginX,
marginY: marginY
};
},
_resetWidthHeight: function() {
var element = this.getElement();
this.set("width", element.width);
this.set("height", element.height);
},
_initElement: function(element, options, callback) {
this.setElement(fabric.util.getById(element), callback, options);
fabric.util.addClass(this.getElement(), fabric.Image.CSS_CANVAS);
},
_initConfig: function(options) {
options || (options = {});
this.setOptions(options);
this._setWidthHeight(options);
if (this._element && this.crossOrigin) {
this._element.crossOrigin = this.crossOrigin;
}
},
_initFilters: function(filters, callback) {
if (filters && filters.length) {
fabric.util.enlivenObjects(filters, function(enlivenedObjects) {
callback && callback(enlivenedObjects);
}, "fabric.Image.filters");
} else {
callback && callback();
}
},
_setWidthHeight: function(options) {
this.width = "width" in options ? options.width : this.getElement() ? this.getElement().width || 0 : 0;
this.height = "height" in options ? options.height : this.getElement() ? this.getElement().height || 0 : 0;
},
complexity: function() {
return 1;
}
});
fabric.Image.CSS_CANVAS = "canvas-img";
fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc;
fabric.Image.fromObject = function(object, callback) {
fabric.util.loadImage(object.src, function(img) {
fabric.Image.prototype._initFilters.call(object, object.filters, function(filters) {
object.filters = filters || [];
fabric.Image.prototype._initFilters.call(object, object.resizeFilters, function(resizeFilters) {
object.resizeFilters = resizeFilters || [];
return new fabric.Image(img, object, callback);
});
});
}, null, object.crossOrigin);
};
fabric.Image.fromURL = function(url, callback, imgOptions) {
fabric.util.loadImage(url, function(img) {
callback && callback(new fabric.Image(img, imgOptions));
}, null, imgOptions && imgOptions.crossOrigin);
};
fabric.Image.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href".split(" "));
fabric.Image.fromElement = function(element, callback, options) {
var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES), preserveAR;
if (parsedAttributes.preserveAspectRatio) {
preserveAR = fabric.util.parsePreserveAspectRatioAttribute(parsedAttributes.preserveAspectRatio);
extend(parsedAttributes, preserveAR);
}
fabric.Image.fromURL(parsedAttributes["xlink:href"], callback, extend(options ? fabric.util.object.clone(options) : {}, parsedAttributes));
};
fabric.Image.async = true;
fabric.Image.pngCompression = 1;
})( true ? exports : this);
fabric.util.object.extend(fabric.Object.prototype, {
_getAngleValueForStraighten: function() {
var angle = this.getAngle() % 360;
if (angle > 0) {
return Math.round((angle - 1) / 90) * 90;
}
return Math.round(angle / 90) * 90;
},
straighten: function() {
this.setAngle(this._getAngleValueForStraighten());
return this;
},
fxStraighten: function(callbacks) {
callbacks = callbacks || {};
var empty = function() {}, onComplete = callbacks.onComplete || empty, onChange = callbacks.onChange || empty, _this = this;
fabric.util.animate({
startValue: this.get("angle"),
endValue: this._getAngleValueForStraighten(),
duration: this.FX_DURATION,
onChange: function(value) {
_this.setAngle(value);
onChange();
},
onComplete: function() {
_this.setCoords();
onComplete();
},
onStart: function() {
_this.set("active", false);
}
});
return this;
}
});
fabric.util.object.extend(fabric.StaticCanvas.prototype, {
straightenObject: function(object) {
object.straighten();
this.renderAll();
return this;
},
fxStraightenObject: function(object) {
object.fxStraighten({
onChange: this.renderAll.bind(this)
});
return this;
}
});
fabric.Image.filters = fabric.Image.filters || {};
fabric.Image.filters.BaseFilter = fabric.util.createClass({
type: "BaseFilter",
initialize: function(options) {
if (options) {
this.setOptions(options);
}
},
setOptions: function(options) {
for (var prop in options) {
this[prop] = options[prop];
}
},
toObject: function() {
return {
type: this.type
};
},
toJSON: function() {
return this.toObject();
}
});
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.Brightness = createClass(filters.BaseFilter, {
type: "Brightness",
initialize: function(options) {
options = options || {};
this.brightness = options.brightness || 0;
},
applyTo: function(canvasEl) {
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, brightness = this.brightness;
for (var i = 0, len = data.length; i < len; i += 4) {
data[i] += brightness;
data[i + 1] += brightness;
data[i + 2] += brightness;
}
context.putImageData(imageData, 0, 0);
},
toObject: function() {
return extend(this.callSuper("toObject"), {
brightness: this.brightness
});
}
});
fabric.Image.filters.Brightness.fromObject = function(object) {
return new fabric.Image.filters.Brightness(object);
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.Convolute = createClass(filters.BaseFilter, {
type: "Convolute",
initialize: function(options) {
options = options || {};
this.opaque = options.opaque;
this.matrix = options.matrix || [ 0, 0, 0, 0, 1, 0, 0, 0, 0 ];
},
applyTo: function(canvasEl) {
var weights = this.matrix, context = canvasEl.getContext("2d"), pixels = context.getImageData(0, 0, canvasEl.width, canvasEl.height), side = Math.round(Math.sqrt(weights.length)), halfSide = Math.floor(side / 2), src = pixels.data, sw = pixels.width, sh = pixels.height, output = context.createImageData(sw, sh), dst = output.data, alphaFac = this.opaque ? 1 : 0, r, g, b, a, dstOff, scx, scy, srcOff, wt;
for (var y = 0; y < sh; y++) {
for (var x = 0; x < sw; x++) {
dstOff = (y * sw + x) * 4;
r = 0;
g = 0;
b = 0;
a = 0;
for (var cy = 0; cy < side; cy++) {
for (var cx = 0; cx < side; cx++) {
scy = y + cy - halfSide;
scx = x + cx - halfSide;
if (scy < 0 || scy > sh || scx < 0 || scx > sw) {
continue;
}
srcOff = (scy * sw + scx) * 4;
wt = weights[cy * side + cx];
r += src[srcOff] * wt;
g += src[srcOff + 1] * wt;
b += src[srcOff + 2] * wt;
a += src[srcOff + 3] * wt;
}
}
dst[dstOff] = r;
dst[dstOff + 1] = g;
dst[dstOff + 2] = b;
dst[dstOff + 3] = a + alphaFac * (255 - a);
}
}
context.putImageData(output, 0, 0);
},
toObject: function() {
return extend(this.callSuper("toObject"), {
opaque: this.opaque,
matrix: this.matrix
});
}
});
fabric.Image.filters.Convolute.fromObject = function(object) {
return new fabric.Image.filters.Convolute(object);
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.GradientTransparency = createClass(filters.BaseFilter, {
type: "GradientTransparency",
initialize: function(options) {
options = options || {};
this.threshold = options.threshold || 100;
},
applyTo: function(canvasEl) {
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, threshold = this.threshold, total = data.length;
for (var i = 0, len = data.length; i < len; i += 4) {
data[i + 3] = threshold + 255 * (total - i) / total;
}
context.putImageData(imageData, 0, 0);
},
toObject: function() {
return extend(this.callSuper("toObject"), {
threshold: this.threshold
});
}
});
fabric.Image.filters.GradientTransparency.fromObject = function(object) {
return new fabric.Image.filters.GradientTransparency(object);
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.Grayscale = createClass(filters.BaseFilter, {
type: "Grayscale",
applyTo: function(canvasEl) {
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, len = imageData.width * imageData.height * 4, index = 0, average;
while (index < len) {
average = (data[index] + data[index + 1] + data[index + 2]) / 3;
data[index] = average;
data[index + 1] = average;
data[index + 2] = average;
index += 4;
}
context.putImageData(imageData, 0, 0);
}
});
fabric.Image.filters.Grayscale.fromObject = function() {
return new fabric.Image.filters.Grayscale();
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.Invert = createClass(filters.BaseFilter, {
type: "Invert",
applyTo: function(canvasEl) {
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i;
for (i = 0; i < iLen; i += 4) {
data[i] = 255 - data[i];
data[i + 1] = 255 - data[i + 1];
data[i + 2] = 255 - data[i + 2];
}
context.putImageData(imageData, 0, 0);
}
});
fabric.Image.filters.Invert.fromObject = function() {
return new fabric.Image.filters.Invert();
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.Mask = createClass(filters.BaseFilter, {
type: "Mask",
initialize: function(options) {
options = options || {};
this.mask = options.mask;
this.channel = [ 0, 1, 2, 3 ].indexOf(options.channel) > -1 ? options.channel : 0;
},
applyTo: function(canvasEl) {
if (!this.mask) {
return;
}
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, maskEl = this.mask.getElement(), maskCanvasEl = fabric.util.createCanvasElement(), channel = this.channel, i, iLen = imageData.width * imageData.height * 4;
maskCanvasEl.width = canvasEl.width;
maskCanvasEl.height = canvasEl.height;
maskCanvasEl.getContext("2d").drawImage(maskEl, 0, 0, canvasEl.width, canvasEl.height);
var maskImageData = maskCanvasEl.getContext("2d").getImageData(0, 0, canvasEl.width, canvasEl.height), maskData = maskImageData.data;
for (i = 0; i < iLen; i += 4) {
data[i + 3] = maskData[i + channel];
}
context.putImageData(imageData, 0, 0);
},
toObject: function() {
return extend(this.callSuper("toObject"), {
mask: this.mask.toObject(),
channel: this.channel
});
}
});
fabric.Image.filters.Mask.fromObject = function(object, callback) {
fabric.util.loadImage(object.mask.src, function(img) {
object.mask = new fabric.Image(img, object.mask);
callback && callback(new fabric.Image.filters.Mask(object));
});
};
fabric.Image.filters.Mask.async = true;
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.Noise = createClass(filters.BaseFilter, {
type: "Noise",
initialize: function(options) {
options = options || {};
this.noise = options.noise || 0;
},
applyTo: function(canvasEl) {
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, noise = this.noise, rand;
for (var i = 0, len = data.length; i < len; i += 4) {
rand = (.5 - Math.random()) * noise;
data[i] += rand;
data[i + 1] += rand;
data[i + 2] += rand;
}
context.putImageData(imageData, 0, 0);
},
toObject: function() {
return extend(this.callSuper("toObject"), {
noise: this.noise
});
}
});
fabric.Image.filters.Noise.fromObject = function(object) {
return new fabric.Image.filters.Noise(object);
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.Pixelate = createClass(filters.BaseFilter, {
type: "Pixelate",
initialize: function(options) {
options = options || {};
this.blocksize = options.blocksize || 4;
},
applyTo: function(canvasEl) {
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = imageData.height, jLen = imageData.width, index, i, j, r, g, b, a;
for (i = 0; i < iLen; i += this.blocksize) {
for (j = 0; j < jLen; j += this.blocksize) {
index = i * 4 * jLen + j * 4;
r = data[index];
g = data[index + 1];
b = data[index + 2];
a = data[index + 3];
for (var _i = i, _ilen = i + this.blocksize; _i < _ilen; _i++) {
for (var _j = j, _jlen = j + this.blocksize; _j < _jlen; _j++) {
index = _i * 4 * jLen + _j * 4;
data[index] = r;
data[index + 1] = g;
data[index + 2] = b;
data[index + 3] = a;
}
}
}
}
context.putImageData(imageData, 0, 0);
},
toObject: function() {
return extend(this.callSuper("toObject"), {
blocksize: this.blocksize
});
}
});
fabric.Image.filters.Pixelate.fromObject = function(object) {
return new fabric.Image.filters.Pixelate(object);
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.RemoveWhite = createClass(filters.BaseFilter, {
type: "RemoveWhite",
initialize: function(options) {
options = options || {};
this.threshold = options.threshold || 30;
this.distance = options.distance || 20;
},
applyTo: function(canvasEl) {
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, threshold = this.threshold, distance = this.distance, limit = 255 - threshold, abs = Math.abs, r, g, b;
for (var i = 0, len = data.length; i < len; i += 4) {
r = data[i];
g = data[i + 1];
b = data[i + 2];
if (r > limit && g > limit && b > limit && abs(r - g) < distance && abs(r - b) < distance && abs(g - b) < distance) {
data[i + 3] = 0;
}
}
context.putImageData(imageData, 0, 0);
},
toObject: function() {
return extend(this.callSuper("toObject"), {
threshold: this.threshold,
distance: this.distance
});
}
});
fabric.Image.filters.RemoveWhite.fromObject = function(object) {
return new fabric.Image.filters.RemoveWhite(object);
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.Sepia = createClass(filters.BaseFilter, {
type: "Sepia",
applyTo: function(canvasEl) {
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i, avg;
for (i = 0; i < iLen; i += 4) {
avg = .3 * data[i] + .59 * data[i + 1] + .11 * data[i + 2];
data[i] = avg + 100;
data[i + 1] = avg + 50;
data[i + 2] = avg + 255;
}
context.putImageData(imageData, 0, 0);
}
});
fabric.Image.filters.Sepia.fromObject = function() {
return new fabric.Image.filters.Sepia();
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.Sepia2 = createClass(filters.BaseFilter, {
type: "Sepia2",
applyTo: function(canvasEl) {
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i, r, g, b;
for (i = 0; i < iLen; i += 4) {
r = data[i];
g = data[i + 1];
b = data[i + 2];
data[i] = (r * .393 + g * .769 + b * .189) / 1.351;
data[i + 1] = (r * .349 + g * .686 + b * .168) / 1.203;
data[i + 2] = (r * .272 + g * .534 + b * .131) / 2.14;
}
context.putImageData(imageData, 0, 0);
}
});
fabric.Image.filters.Sepia2.fromObject = function() {
return new fabric.Image.filters.Sepia2();
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.Tint = createClass(filters.BaseFilter, {
type: "Tint",
initialize: function(options) {
options = options || {};
this.color = options.color || "#000000";
this.opacity = typeof options.opacity !== "undefined" ? options.opacity : new fabric.Color(this.color).getAlpha();
},
applyTo: function(canvasEl) {
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i, tintR, tintG, tintB, r, g, b, alpha1, source;
source = new fabric.Color(this.color).getSource();
tintR = source[0] * this.opacity;
tintG = source[1] * this.opacity;
tintB = source[2] * this.opacity;
alpha1 = 1 - this.opacity;
for (i = 0; i < iLen; i += 4) {
r = data[i];
g = data[i + 1];
b = data[i + 2];
data[i] = tintR + r * alpha1;
data[i + 1] = tintG + g * alpha1;
data[i + 2] = tintB + b * alpha1;
}
context.putImageData(imageData, 0, 0);
},
toObject: function() {
return extend(this.callSuper("toObject"), {
color: this.color,
opacity: this.opacity
});
}
});
fabric.Image.filters.Tint.fromObject = function(object) {
return new fabric.Image.filters.Tint(object);
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.Multiply = createClass(filters.BaseFilter, {
type: "Multiply",
initialize: function(options) {
options = options || {};
this.color = options.color || "#000000";
},
applyTo: function(canvasEl) {
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i, source;
source = new fabric.Color(this.color).getSource();
for (i = 0; i < iLen; i += 4) {
data[i] *= source[0] / 255;
data[i + 1] *= source[1] / 255;
data[i + 2] *= source[2] / 255;
}
context.putImageData(imageData, 0, 0);
},
toObject: function() {
return extend(this.callSuper("toObject"), {
color: this.color
});
}
});
fabric.Image.filters.Multiply.fromObject = function(object) {
return new fabric.Image.filters.Multiply(object);
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric, filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.Blend = createClass(filters.BaseFilter, {
type: "Blend",
initialize: function(options) {
options = options || {};
this.color = options.color || "#000";
this.image = options.image || false;
this.mode = options.mode || "multiply";
this.alpha = options.alpha || 1;
},
applyTo: function(canvasEl) {
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, tr, tg, tb, r, g, b, _r, _g, _b, source, isImage = false;
if (this.image) {
isImage = true;
var _el = fabric.util.createCanvasElement();
_el.width = this.image.width;
_el.height = this.image.height;
var tmpCanvas = new fabric.StaticCanvas(_el);
tmpCanvas.add(this.image);
var context2 = tmpCanvas.getContext("2d");
source = context2.getImageData(0, 0, tmpCanvas.width, tmpCanvas.height).data;
} else {
source = new fabric.Color(this.color).getSource();
tr = source[0] * this.alpha;
tg = source[1] * this.alpha;
tb = source[2] * this.alpha;
}
for (var i = 0, len = data.length; i < len; i += 4) {
r = data[i];
g = data[i + 1];
b = data[i + 2];
if (isImage) {
tr = source[i] * this.alpha;
tg = source[i + 1] * this.alpha;
tb = source[i + 2] * this.alpha;
}
switch (this.mode) {
case "multiply":
data[i] = r * tr / 255;
data[i + 1] = g * tg / 255;
data[i + 2] = b * tb / 255;
break;
case "screen":
data[i] = 1 - (1 - r) * (1 - tr);
data[i + 1] = 1 - (1 - g) * (1 - tg);
data[i + 2] = 1 - (1 - b) * (1 - tb);
break;
case "add":
data[i] = Math.min(255, r + tr);
data[i + 1] = Math.min(255, g + tg);
data[i + 2] = Math.min(255, b + tb);
break;
case "diff":
case "difference":
data[i] = Math.abs(r - tr);
data[i + 1] = Math.abs(g - tg);
data[i + 2] = Math.abs(b - tb);
break;
case "subtract":
_r = r - tr;
_g = g - tg;
_b = b - tb;
data[i] = _r < 0 ? 0 : _r;
data[i + 1] = _g < 0 ? 0 : _g;
data[i + 2] = _b < 0 ? 0 : _b;
break;
case "darken":
data[i] = Math.min(r, tr);
data[i + 1] = Math.min(g, tg);
data[i + 2] = Math.min(b, tb);
break;
case "lighten":
data[i] = Math.max(r, tr);
data[i + 1] = Math.max(g, tg);
data[i + 2] = Math.max(b, tb);
break;
}
}
context.putImageData(imageData, 0, 0);
},
toObject: function() {
return {
color: this.color,
image: this.image,
mode: this.mode,
alpha: this.alpha
};
}
});
fabric.Image.filters.Blend.fromObject = function(object) {
return new fabric.Image.filters.Blend(object);
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), pow = Math.pow, floor = Math.floor, sqrt = Math.sqrt, abs = Math.abs, max = Math.max, round = Math.round, sin = Math.sin, ceil = Math.ceil, filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.Resize = createClass(filters.BaseFilter, {
type: "Resize",
resizeType: "hermite",
scaleX: 0,
scaleY: 0,
lanczosLobes: 3,
applyTo: function(canvasEl, scaleX, scaleY) {
if (scaleX === 1 && scaleY === 1) {
return;
}
this.rcpScaleX = 1 / scaleX;
this.rcpScaleY = 1 / scaleY;
var oW = canvasEl.width, oH = canvasEl.height, dW = round(oW * scaleX), dH = round(oH * scaleY), imageData;
if (this.resizeType === "sliceHack") {
imageData = this.sliceByTwo(canvasEl, oW, oH, dW, dH);
}
if (this.resizeType === "hermite") {
imageData = this.hermiteFastResize(canvasEl, oW, oH, dW, dH);
}
if (this.resizeType === "bilinear") {
imageData = this.bilinearFiltering(canvasEl, oW, oH, dW, dH);
}
if (this.resizeType === "lanczos") {
imageData = this.lanczosResize(canvasEl, oW, oH, dW, dH);
}
canvasEl.width = dW;
canvasEl.height = dH;
canvasEl.getContext("2d").putImageData(imageData, 0, 0);
},
sliceByTwo: function(canvasEl, oW, oH, dW, dH) {
var context = canvasEl.getContext("2d"), imageData, multW = .5, multH = .5, signW = 1, signH = 1, doneW = false, doneH = false, stepW = oW, stepH = oH, tmpCanvas = fabric.util.createCanvasElement(), tmpCtx = tmpCanvas.getContext("2d");
dW = floor(dW);
dH = floor(dH);
tmpCanvas.width = max(dW, oW);
tmpCanvas.height = max(dH, oH);
if (dW > oW) {
multW = 2;
signW = -1;
}
if (dH > oH) {
multH = 2;
signH = -1;
}
imageData = context.getImageData(0, 0, oW, oH);
canvasEl.width = max(dW, oW);
canvasEl.height = max(dH, oH);
context.putImageData(imageData, 0, 0);
while (!doneW || !doneH) {
oW = stepW;
oH = stepH;
if (dW * signW < floor(stepW * multW * signW)) {
stepW = floor(stepW * multW);
} else {
stepW = dW;
doneW = true;
}
if (dH * signH < floor(stepH * multH * signH)) {
stepH = floor(stepH * multH);
} else {
stepH = dH;
doneH = true;
}
imageData = context.getImageData(0, 0, oW, oH);
tmpCtx.putImageData(imageData, 0, 0);
context.clearRect(0, 0, stepW, stepH);
context.drawImage(tmpCanvas, 0, 0, oW, oH, 0, 0, stepW, stepH);
}
return context.getImageData(0, 0, dW, dH);
},
lanczosResize: function(canvasEl, oW, oH, dW, dH) {
function lanczosCreate(lobes) {
return function(x) {
if (x > lobes) {
return 0;
}
x *= Math.PI;
if (abs(x) < 1e-16) {
return 1;
}
var xx = x / lobes;
return sin(x) * sin(xx) / x / xx;
};
}
function process(u) {
var v, i, weight, idx, a, red, green, blue, alpha, fX, fY;
center.x = (u + .5) * ratioX;
icenter.x = floor(center.x);
for (v = 0; v < dH; v++) {
center.y = (v + .5) * ratioY;
icenter.y = floor(center.y);
a = 0;
red = 0;
green = 0;
blue = 0;
alpha = 0;
for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) {
if (i < 0 || i >= oW) {
continue;
}
fX = floor(1e3 * abs(i - center.x));
if (!cacheLanc[fX]) {
cacheLanc[fX] = {};
}
for (var j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) {
if (j < 0 || j >= oH) {
continue;
}
fY = floor(1e3 * abs(j - center.y));
if (!cacheLanc[fX][fY]) {
cacheLanc[fX][fY] = lanczos(sqrt(pow(fX * rcpRatioX, 2) + pow(fY * rcpRatioY, 2)) / 1e3);
}
weight = cacheLanc[fX][fY];
if (weight > 0) {
idx = (j * oW + i) * 4;
a += weight;
red += weight * srcData[idx];
green += weight * srcData[idx + 1];
blue += weight * srcData[idx + 2];
alpha += weight * srcData[idx + 3];
}
}
}
idx = (v * dW + u) * 4;
destData[idx] = red / a;
destData[idx + 1] = green / a;
destData[idx + 2] = blue / a;
destData[idx + 3] = alpha / a;
}
if (++u < dW) {
return process(u);
} else {
return destImg;
}
}
var context = canvasEl.getContext("2d"), srcImg = context.getImageData(0, 0, oW, oH), destImg = context.getImageData(0, 0, dW, dH), srcData = srcImg.data, destData = destImg.data, lanczos = lanczosCreate(this.lanczosLobes), ratioX = this.rcpScaleX, ratioY = this.rcpScaleY, rcpRatioX = 2 / this.rcpScaleX, rcpRatioY = 2 / this.rcpScaleY, range2X = ceil(ratioX * this.lanczosLobes / 2), range2Y = ceil(ratioY * this.lanczosLobes / 2), cacheLanc = {}, center = {}, icenter = {};
return process(0);
},
bilinearFiltering: function(canvasEl, oW, oH, dW, dH) {
var a, b, c, d, x, y, i, j, xDiff, yDiff, chnl, color, offset = 0, origPix, ratioX = this.rcpScaleX, ratioY = this.rcpScaleY, context = canvasEl.getContext("2d"), w4 = 4 * (oW - 1), img = context.getImageData(0, 0, oW, oH), pixels = img.data, destImage = context.getImageData(0, 0, dW, dH), destPixels = destImage.data;
for (i = 0; i < dH; i++) {
for (j = 0; j < dW; j++) {
x = floor(ratioX * j);
y = floor(ratioY * i);
xDiff = ratioX * j - x;
yDiff = ratioY * i - y;
origPix = 4 * (y * oW + x);
for (chnl = 0; chnl < 4; chnl++) {
a = pixels[origPix + chnl];
b = pixels[origPix + 4 + chnl];
c = pixels[origPix + w4 + chnl];
d = pixels[origPix + w4 + 4 + chnl];
color = a * (1 - xDiff) * (1 - yDiff) + b * xDiff * (1 - yDiff) + c * yDiff * (1 - xDiff) + d * xDiff * yDiff;
destPixels[offset++] = color;
}
}
}
return destImage;
},
hermiteFastResize: function(canvasEl, oW, oH, dW, dH) {
var ratioW = this.rcpScaleX, ratioH = this.rcpScaleY, ratioWHalf = ceil(ratioW / 2), ratioHHalf = ceil(ratioH / 2), context = canvasEl.getContext("2d"), img = context.getImageData(0, 0, oW, oH), data = img.data, img2 = context.getImageData(0, 0, dW, dH), data2 = img2.data;
for (var j = 0; j < dH; j++) {
for (var i = 0; i < dW; i++) {
var x2 = (i + j * dW) * 4, weight = 0, weights = 0, weightsAlpha = 0, gxR = 0, gxG = 0, gxB = 0, gxA = 0, centerY = (j + .5) * ratioH;
for (var yy = floor(j * ratioH); yy < (j + 1) * ratioH; yy++) {
var dy = abs(centerY - (yy + .5)) / ratioHHalf, centerX = (i + .5) * ratioW, w0 = dy * dy;
for (var xx = floor(i * ratioW); xx < (i + 1) * ratioW; xx++) {
var dx = abs(centerX - (xx + .5)) / ratioWHalf, w = sqrt(w0 + dx * dx);
if (w > 1 && w < -1) {
continue;
}
weight = 2 * w * w * w - 3 * w * w + 1;
if (weight > 0) {
dx = 4 * (xx + yy * oW);
gxA += weight * data[dx + 3];
weightsAlpha += weight;
if (data[dx + 3] < 255) {
weight = weight * data[dx + 3] / 250;
}
gxR += weight * data[dx];
gxG += weight * data[dx + 1];
gxB += weight * data[dx + 2];
weights += weight;
}
}
}
data2[x2] = gxR / weights;
data2[x2 + 1] = gxG / weights;
data2[x2 + 2] = gxB / weights;
data2[x2 + 3] = gxA / weightsAlpha;
}
}
return img2;
},
toObject: function() {
return {
type: this.type,
scaleX: this.scaleX,
scaleY: this.scaleY,
resizeType: this.resizeType,
lanczosLobes: this.lanczosLobes
};
}
});
fabric.Image.filters.Resize.fromObject = function(object) {
return new fabric.Image.filters.Resize(object);
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.ColorMatrix = createClass(filters.BaseFilter, {
type: "ColorMatrix",
initialize: function(options) {
options || (options = {});
this.matrix = options.matrix || [ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0 ];
},
applyTo: function(canvasEl) {
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i, r, g, b, a, m = this.matrix;
for (i = 0; i < iLen; i += 4) {
r = data[i];
g = data[i + 1];
b = data[i + 2];
a = data[i + 3];
data[i] = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4];
data[i + 1] = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9];
data[i + 2] = r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14];
data[i + 3] = r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19];
}
context.putImageData(imageData, 0, 0);
},
toObject: function() {
return extend(this.callSuper("toObject"), {
type: this.type,
matrix: this.matrix
});
}
});
fabric.Image.filters.ColorMatrix.fromObject = function(object) {
return new fabric.Image.filters.ColorMatrix(object);
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.Contrast = createClass(filters.BaseFilter, {
type: "Contrast",
initialize: function(options) {
options = options || {};
this.contrast = options.contrast || 0;
},
applyTo: function(canvasEl) {
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, contrastF = 259 * (this.contrast + 255) / (255 * (259 - this.contrast));
for (var i = 0, len = data.length; i < len; i += 4) {
data[i] = contrastF * (data[i] - 128) + 128;
data[i + 1] = contrastF * (data[i + 1] - 128) + 128;
data[i + 2] = contrastF * (data[i + 2] - 128) + 128;
}
context.putImageData(imageData, 0, 0);
},
toObject: function() {
return extend(this.callSuper("toObject"), {
contrast: this.contrast
});
}
});
fabric.Image.filters.Contrast.fromObject = function(object) {
return new fabric.Image.filters.Contrast(object);
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass;
filters.Saturate = createClass(filters.BaseFilter, {
type: "Saturate",
initialize: function(options) {
options = options || {};
this.saturate = options.saturate || 0;
},
applyTo: function(canvasEl) {
var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, max, adjust = -this.saturate * .01;
for (var i = 0, len = data.length; i < len; i += 4) {
max = Math.max(data[i], data[i + 1], data[i + 2]);
data[i] += max !== data[i] ? (max - data[i]) * adjust : 0;
data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0;
data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0;
}
context.putImageData(imageData, 0, 0);
},
toObject: function() {
return extend(this.callSuper("toObject"), {
saturate: this.saturate
});
}
});
fabric.Image.filters.Saturate.fromObject = function(object) {
return new fabric.Image.filters.Saturate(object);
};
})( true ? exports : this);
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), clone = fabric.util.object.clone, toFixed = fabric.util.toFixed, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, MIN_TEXT_WIDTH = 2, LOADED_CACHE = {};
if (fabric.Text) {
fabric.warn("fabric.Text is already defined");
return;
}
var stateProperties = fabric.Object.prototype.stateProperties.concat();
stateProperties.push("fontFamily", "fontWeight", "fontSize", "text", "textDecoration", "textAlign", "fontStyle", "lineHeight", "textBackgroundColor");
fabric.Text = fabric.util.createClass(fabric.Object, {
_dimensionAffectingProps: {
fontSize: true,
fontWeight: true,
fontFamily: true,
fontStyle: true,
lineHeight: true,
text: true,
charSpacing: true,
textAlign: true,
strokeWidth: false
},
_reNewline: /\r?\n/,
_reSpacesAndTabs: /[ \t\r]+/g,
type: "text",
fontSize: 40,
fontWeight: "normal",
fontFamily: "Times New Roman",
textDecoration: "",
textAlign: "left",
fontStyle: "",
lineHeight: 1.16,
textBackgroundColor: "",
stateProperties: stateProperties,
stroke: null,
shadow: null,
_fontSizeFraction: .25,
_fontSizeMult: 1.13,
charSpacing: 0,
initialize: function(text, options) {
options = options || {};
this.text = text;
this.__skipDimension = true;
this.setOptions(options);
this.__skipDimension = false;
this._initDimensions();
},
_initDimensions: function(ctx) {
if (this.__skipDimension) {
return;
}
if (!ctx) {
ctx = fabric.util.createCanvasElement().getContext("2d");
this._setTextStyles(ctx);
}
this._textLines = this._splitTextIntoLines();
this._clearCache();
this.width = this._getTextWidth(ctx) || this.cursorWidth || MIN_TEXT_WIDTH;
this.height = this._getTextHeight(ctx);
},
toString: function() {
return "#<fabric.Text (" + this.complexity() + '): { "text": "' + this.text + '", "fontFamily": "' + this.fontFamily + '" }>';
},
_render: function(ctx) {
this.clipTo && fabric.util.clipContext(this, ctx);
this._setOpacity(ctx);
this._setShadow(ctx);
this._setupCompositeOperation(ctx);
this._renderTextBackground(ctx);
this._renderTextOuterDecoration(ctx);
this._setStrokeStyles(ctx);
this._setFillStyles(ctx);
this._setGradient(ctx);
this._renderText(ctx);
this._renderTextDecoration(ctx);
this.clipTo && ctx.restore();
},
_renderText: function(ctx) {
this._renderTextStroke(ctx);
this._renderTextFill(ctx);
},
_setTextStyles: function(ctx) {
ctx.textBaseline = "alphabetic";
ctx.font = this._getFontDeclaration();
},
_getTextHeight: function() {
return this._getHeightOfSingleLine() + (this._textLines.length - 1) * this._getHeightOfLine();
},
_getTextWidth: function(ctx) {
var maxWidth = this._getLineWidth(ctx, 0);
for (var i = 1, len = this._textLines.length; i < len; i++) {
var currentLineWidth = this._getLineWidth(ctx, i);
if (currentLineWidth > maxWidth) {
maxWidth = currentLineWidth;
}
}
return maxWidth;
},
_getNonTransformedDimensions: function() {
return {
x: this.width,
y: this.height
};
},
_renderChars: function(method, ctx, chars, left, top) {
var shortM = method.slice(0, -4), char, width;
if (this[shortM].toLive) {
var offsetX = -this.width / 2 + this[shortM].offsetX || 0, offsetY = -this.height / 2 + this[shortM].offsetY || 0;
ctx.save();
ctx.translate(offsetX, offsetY);
left -= offsetX;
top -= offsetY;
}
if (this.charSpacing !== 0) {
var additionalSpace = this._getWidthOfCharSpacing();
chars = chars.split("");
for (var i = 0, len = chars.length; i < len; i++) {
char = chars[i];
width = ctx.measureText(char).width + additionalSpace;
ctx[method](char, left, top);
left += width > 0 ? width : 0;
}
} else {
ctx[method](chars, left, top);
}
this[shortM].toLive && ctx.restore();
},
_renderTextLine: function(method, ctx, line, left, top, lineIndex) {
top -= this.fontSize * this._fontSizeFraction;
var lineWidth = this._getLineWidth(ctx, lineIndex);
if (this.textAlign !== "justify" || this.width < lineWidth) {
this._renderChars(method, ctx, line, left, top, lineIndex);
return;
}
var words = line.split(/\s+/), charOffset = 0, wordsWidth = this._getWidthOfWords(ctx, words.join(" "), lineIndex, 0), widthDiff = this.width - wordsWidth, numSpaces = words.length - 1, spaceWidth = numSpaces > 0 ? widthDiff / numSpaces : 0, leftOffset = 0, word;
for (var i = 0, len = words.length; i < len; i++) {
while (line[charOffset] === " " && charOffset < line.length) {
charOffset++;
}
word = words[i];
this._renderChars(method, ctx, word, left + leftOffset, top, lineIndex, charOffset);
leftOffset += this._getWidthOfWords(ctx, word, lineIndex, charOffset) + spaceWidth;
charOffset += word.length;
}
},
_getWidthOfWords: function(ctx, word) {
var width = ctx.measureText(word).width, charCount, additionalSpace;
if (this.charSpacing !== 0) {
charCount = word.split("").length;
additionalSpace = charCount * this._getWidthOfCharSpacing();
width += additionalSpace;
}
return width > 0 ? width : 0;
},
_getLeftOffset: function() {
return -this.width / 2;
},
_getTopOffset: function() {
return -this.height / 2;
},
isEmptyStyles: function() {
return true;
},
_renderTextCommon: function(ctx, method) {
var lineHeights = 0, left = this._getLeftOffset(), top = this._getTopOffset();
for (var i = 0, len = this._textLines.length; i < len; i++) {
var heightOfLine = this._getHeightOfLine(ctx, i), maxHeight = heightOfLine / this.lineHeight, lineWidth = this._getLineWidth(ctx, i), leftOffset = this._getLineLeftOffset(lineWidth);
this._renderTextLine(method, ctx, this._textLines[i], left + leftOffset, top + lineHeights + maxHeight, i);
lineHeights += heightOfLine;
}
},
_renderTextFill: function(ctx) {
if (!this.fill && this.isEmptyStyles()) {
return;
}
this._renderTextCommon(ctx, "fillText");
},
_setGradient: function(ctx) {
if (this.gradient) {
var height = this.fontSize;
var width = this.width;
var array = this.gradient.array;
var isHorizon = this.gradient.horizon ? true : false;
var gradient = ctx.createLinearGradient(0, 0, isHorizon ? width / 2 : 0, !isHorizon ? height / 2 : 0);
for (var i in array) {
var item = array[i];
if (item.point !== undefined && item.point <= 1 && item.color) {
gradient.addColorStop(item.point, item.color);
}
}
ctx.fillStyle = gradient;
} else {
ctx.fillStyle = this.fill;
}
},
_renderTextStroke: function(ctx) {
if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) {
return;
}
if (this.shadow && !this.shadow.affectStroke) {
this._removeShadow(ctx);
}
ctx.save();
this._setLineDash(ctx, this.strokedashArray);
ctx.beginPath();
this._renderTextCommon(ctx, "strokeText");
ctx.closePath();
ctx.restore();
},
_getHeightOfLine: function() {
return this._getHeightOfSingleLine() * this.lineHeight;
},
_getHeightOfSingleLine: function() {
return this.fontSize * this._fontSizeMult;
},
_renderTextBackground: function(ctx) {
this._renderBackground(ctx);
this._renderTextLinesBackground(ctx);
},
_renderTextLinesBackground: function(ctx) {
if (!this.textBackgroundColor) {
return;
}
var lineTopOffset = 0, heightOfLine, lineWidth, lineLeftOffset;
ctx.fillStyle = this.textBackgroundColor;
for (var i = 0, len = this._textLines.length; i < len; i++) {
heightOfLine = this._getHeightOfLine(ctx, i);
lineWidth = this._getLineWidth(ctx, i);
if (lineWidth > 0) {
lineLeftOffset = this._getLineLeftOffset(lineWidth);
ctx.fillRect(this._getLeftOffset() + lineLeftOffset, this._getTopOffset() + lineTopOffset, lineWidth, heightOfLine / this.lineHeight);
}
lineTopOffset += heightOfLine;
}
this._removeShadow(ctx);
},
_getLineLeftOffset: function(lineWidth) {
if (this.textAlign === "center") {
return (this.width - lineWidth) / 2;
}
if (this.textAlign === "right") {
return this.width - lineWidth;
}
return 0;
},
_clearCache: function() {
this.__lineWidths = [];
this.__lineHeights = [];
},
_shouldClearCache: function() {
var shouldClear = false;
if (this._forceClearCache) {
this._forceClearCache = false;
return true;
}
for (var prop in this._dimensionAffectingProps) {
if (this["__" + prop] !== this[prop]) {
this["__" + prop] = this[prop];
shouldClear = true;
}
}
return shouldClear;
},
_getLineWidth: function(ctx, lineIndex) {
if (this.__lineWidths[lineIndex]) {
return this.__lineWidths[lineIndex] === -1 ? this.width : this.__lineWidths[lineIndex];
}
var width, wordCount, line = this._textLines[lineIndex];
if (line === "") {
width = 0;
} else {
width = this._measureLine(ctx, lineIndex);
}
this.__lineWidths[lineIndex] = width;
if (width && this.textAlign === "justify") {
wordCount = line.split(/\s+/);
if (wordCount.length > 1) {
this.__lineWidths[lineIndex] = -1;
}
}
return width;
},
_getWidthOfCharSpacing: function() {
if (this.charSpacing !== 0) {
return this.fontSize * this.charSpacing / 1e3;
}
return 0;
},
_measureLine: function(ctx, lineIndex) {
var line = this._textLines[lineIndex], width = ctx.measureText(line).width, additionalSpace = 0, charCount, finalWidth;
if (this.charSpacing !== 0) {
charCount = line.split("").length;
additionalSpace = (charCount - 1) * this._getWidthOfCharSpacing();
}
finalWidth = width + additionalSpace;
return finalWidth > 0 ? finalWidth : 0;
},
_renderTextDecoration: function(ctx) {
if (!this.textDecoration) {
return;
}
var halfOfVerticalBox = this.height / 2, _this = this, offsets = [];
function renderLinesAtOffset(offsets) {
var i, lineHeight = 0, len, j, oLen, lineWidth, lineLeftOffset, heightOfLine;
for (i = 0, len = _this._textLines.length; i < len; i++) {
lineWidth = _this._getLineWidth(ctx, i);
lineLeftOffset = _this._getLineLeftOffset(lineWidth);
heightOfLine = _this._getHeightOfLine(ctx, i);
for (j = 0, oLen = offsets.length; j < oLen; j++) {
ctx.fillRect(_this._getLeftOffset() + lineLeftOffset, lineHeight + (_this._fontSizeMult - 1 + offsets[j]) * _this.fontSize - halfOfVerticalBox, lineWidth, _this.fontSize / 15);
}
lineHeight += heightOfLine;
}
}
if (this.textDecoration.indexOf("underline") > -1) {
offsets.push(.85);
}
if (this.textDecoration.indexOf("line-through") > -1) {
offsets.push(.43);
}
if (this.textDecoration.indexOf("overline") > -1) {
offsets.push(-.12);
}
if (offsets.length > 0) {
renderLinesAtOffset(offsets);
}
},
_renderTextOuterDecoration: function(ctx) {
if (!this.outerDecoration) {
return;
}
ctx.lineWidth = this.outerDecoration.borderLineWidth;
ctx.strokeStyle = this.outerDecoration.borderColor;
var offsetX = this.outerDecoration.offsetX || 0, offsetY = this.outerDecoration.offsetY || 0, x = -this.width / 2 - offsetX, y = -this.height / 2 - offsetY, w = this.width + offsetX * 2, h = this.height + offsetY * 2, r = this.outerDecoration.radius || 4, cornerSize = this.outerDecoration.cornerSize || 30, x1 = x - cornerSize / 2, y1 = y - cornerSize / 2, x2 = x - cornerSize / 2 + w, y2 = y - cornerSize / 2 + h, loadingImg = 0;
var min_size = Math.min(w, h);
if (r > min_size / 2) r = min_size / 2;
ctx.beginPath();
ctx.moveTo(x + r, y);
ctx.arcTo(x + w, y, x + w, y + h, r);
ctx.arcTo(x + w, y + h, x, y + h, r);
ctx.arcTo(x, y + h, x, y, r);
ctx.arcTo(x, y, x + w, y, r);
ctx.closePath();
ctx.fillStyle = this.outerDecoration.backgroundColor;
ctx.fill();
ctx.stroke();
var drawImage = function(ctx, that) {
return function(src, x, y, size) {
if (!LOADED_CACHE[src] || LOADED_CACHE[src] && !LOADED_CACHE[src].loaded) {
loadingImg++;
}
that._loadImage(src, function(img, isCache) {
if (!isCache) {
loadingImg--;
}
isCache && ctx.drawImage(img, x, y, size, size);
}, ctx, true, function() {
loadingImg === 0 ? that.render(ctx) : null;
});
};
}(ctx, this);
this.outerDecoration.tl && drawImage(this.outerDecoration.tl, x1, y1, cornerSize, cornerSize);
this.outerDecoration.tr && drawImage(this.outerDecoration.tr, x2, y1, cornerSize, cornerSize);
this.outerDecoration.bl && drawImage(this.outerDecoration.bl, x1, y2, cornerSize, cornerSize);
this.outerDecoration.br && drawImage(this.outerDecoration.br, x2, y2, cornerSize, cornerSize);
loadingImg === 0 ? this.fire("render:success") : null;
},
_loadImage: function(url, callback, context, crossOrigin, onload) {
if (!url) {
callback && callback.call(context, url);
return;
} else if (LOADED_CACHE[url]) {
if (LOADED_CACHE[url].loaded) {
callback && callback.call(context, LOADED_CACHE[url].img, true);
} else {
return;
}
return;
}
var img = fabric.util.createImage();
LOADED_CACHE[url] = {
loaded: false,
img: img
};
img.onload = function() {
callback && callback.call(context, img);
LOADED_CACHE[url].loaded = true;
img = img.onload = img.onerror = null;
onload && onload();
};
img.onerror = function() {
fabric.log("Error loading " + img.src);
callback && callback.call(context, null, true);
img = img.onload = img.onerror = null;
LOADED_CACHE[url] = null;
};
if (url.indexOf("data") !== 0 && crossOrigin) {
img.crossOrigin = crossOrigin;
}
img.src = url;
},
_getFontDeclaration: function() {
return [ fabric.isLikelyNode ? this.fontWeight : this.fontStyle, fabric.isLikelyNode ? this.fontStyle : this.fontWeight, this.fontSize + "px", fabric.isLikelyNode ? '"' + this.fontFamily + '"' : this.fontFamily ].join(" ");
},
render: function(ctx, noTransform) {
if (!this.visible) {
return;
}
ctx.save();
this._setTextStyles(ctx);
if (this._shouldClearCache()) {
this._initDimensions(ctx);
}
this.drawSelectionBackground(ctx);
if (!noTransform) {
this.transform(ctx);
}
if (this.transformMatrix) {
ctx.transform.apply(ctx, this.transformMatrix);
}
if (this.group && this.group.type === "path-group") {
ctx.translate(this.left, this.top);
}
this._render(ctx);
ctx.restore();
},
_splitTextIntoLines: function() {
return this.text.split(this._reNewline);
},
toObject: function(propertiesToInclude) {
var additionalProperties = [ "text", "fontSize", "fontWeight", "fontFamily", "fontStyle", "lineHeight", "textDecoration", "textAlign", "textBackgroundColor", "charSpacing" ].concat(propertiesToInclude);
return this.callSuper("toObject", additionalProperties);
},
toSVG: function(reviver) {
if (!this.ctx) {
this.ctx = fabric.util.createCanvasElement().getContext("2d");
}
var markup = this._createBaseSVGMarkup(), offsets = this._getSVGLeftTopOffsets(this.ctx), textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);
this._wrapSVGTextAndBg(markup, textAndBg);
return reviver ? reviver(markup.join("")) : markup.join("");
},
_getSVGLeftTopOffsets: function(ctx) {
var lineTop = this._getHeightOfLine(ctx, 0), textLeft = -this.width / 2, textTop = 0;
return {
textLeft: textLeft + (this.group && this.group.type === "path-group" ? this.left : 0),
textTop: textTop + (this.group && this.group.type === "path-group" ? -this.top : 0),
lineTop: lineTop
};
},
_wrapSVGTextAndBg: function(markup, textAndBg) {
var noShadow = true, filter = this.getSvgFilter(), style = filter === "" ? "" : ' style="' + filter + '"';
markup.push("\t<g ", this.getSvgId(), 'transform="', this.getSvgTransform(), this.getSvgTransformMatrix(), '"', style, ">\n", textAndBg.textBgRects.join(""), "\t\t<text ", this.fontFamily ? 'font-family="' + this.fontFamily.replace(/"/g, "'") + '" ' : "", this.fontSize ? 'font-size="' + this.fontSize + '" ' : "", this.fontStyle ? 'font-style="' + this.fontStyle + '" ' : "", this.fontWeight ? 'font-weight="' + this.fontWeight + '" ' : "", this.textDecoration ? 'text-decoration="' + this.textDecoration + '" ' : "", 'style="', this.getSvgStyles(noShadow), '" >\n', textAndBg.textSpans.join(""), "\t\t</text>\n", "\t</g>\n");
},
_getSVGTextAndBg: function(textTopOffset, textLeftOffset) {
var textSpans = [], textBgRects = [], height = 0;
this._setSVGBg(textBgRects);
for (var i = 0, len = this._textLines.length; i < len; i++) {
if (this.textBackgroundColor) {
this._setSVGTextLineBg(textBgRects, i, textLeftOffset, textTopOffset, height);
}
this._setSVGTextLineText(i, textSpans, height, textLeftOffset, textTopOffset, textBgRects);
height += this._getHeightOfLine(this.ctx, i);
}
return {
textSpans: textSpans,
textBgRects: textBgRects
};
},
_setSVGTextLineText: function(i, textSpans, height, textLeftOffset, textTopOffset) {
var yPos = this.fontSize * (this._fontSizeMult - this._fontSizeFraction) - textTopOffset + height - this.height / 2;
if (this.textAlign === "justify") {
this._setSVGTextLineJustifed(i, textSpans, yPos, textLeftOffset);
return;
}
textSpans.push('\t\t\t<tspan x="', toFixed(textLeftOffset + this._getLineLeftOffset(this._getLineWidth(this.ctx, i)), NUM_FRACTION_DIGITS), '" ', 'y="', toFixed(yPos, NUM_FRACTION_DIGITS), '" ', this._getFillAttributes(this.fill), ">", fabric.util.string.escapeXml(this._textLines[i]), "</tspan>\n");
},
_setSVGTextLineJustifed: function(i, textSpans, yPos, textLeftOffset) {
var ctx = fabric.util.createCanvasElement().getContext("2d");
this._setTextStyles(ctx);
var line = this._textLines[i], words = line.split(/\s+/), wordsWidth = this._getWidthOfWords(ctx, words.join("")), widthDiff = this.width - wordsWidth, numSpaces = words.length - 1, spaceWidth = numSpaces > 0 ? widthDiff / numSpaces : 0, word, attributes = this._getFillAttributes(this.fill), len;
textLeftOffset += this._getLineLeftOffset(this._getLineWidth(ctx, i));
for (i = 0, len = words.length; i < len; i++) {
word = words[i];
textSpans.push('\t\t\t<tspan x="', toFixed(textLeftOffset, NUM_FRACTION_DIGITS), '" ', 'y="', toFixed(yPos, NUM_FRACTION_DIGITS), '" ', attributes, ">", fabric.util.string.escapeXml(word), "</tspan>\n");
textLeftOffset += this._getWidthOfWords(ctx, word) + spaceWidth;
}
},
_setSVGTextLineBg: function(textBgRects, i, textLeftOffset, textTopOffset, height) {
textBgRects.push("\t\t<rect ", this._getFillAttributes(this.textBackgroundColor), ' x="', toFixed(textLeftOffset + this._getLineLeftOffset(this._getLineWidth(this.ctx, i)), NUM_FRACTION_DIGITS), '" y="', toFixed(height - this.height / 2, NUM_FRACTION_DIGITS), '" width="', toFixed(this._getLineWidth(this.ctx, i), NUM_FRACTION_DIGITS), '" height="', toFixed(this._getHeightOfLine(this.ctx, i) / this.lineHeight, NUM_FRACTION_DIGITS), '"></rect>\n');
},
_setSVGBg: function(textBgRects) {
if (this.backgroundColor) {
textBgRects.push("\t\t<rect ", this._getFillAttributes(this.backgroundColor), ' x="', toFixed(-this.width / 2, NUM_FRACTION_DIGITS), '" y="', toFixed(-this.height / 2, NUM_FRACTION_DIGITS), '" width="', toFixed(this.width, NUM_FRACTION_DIGITS), '" height="', toFixed(this.height, NUM_FRACTION_DIGITS), '"></rect>\n');
}
},
_getFillAttributes: function(value) {
var fillColor = value && typeof value === "string" ? new fabric.Color(value) : "";
if (!fillColor || !fillColor.getSource() || fillColor.getAlpha() === 1) {
return 'fill="' + value + '"';
}
return 'opacity="' + fillColor.getAlpha() + '" fill="' + fillColor.setAlpha(1).toRgb() + '"';
},
_set: function(key, value) {
this.callSuper("_set", key, value);
if (key in this._dimensionAffectingProps) {
this._initDimensions();
this.setCoords();
}
},
complexity: function() {
return 1;
}
});
fabric.Text.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("x y dx dy font-family font-style font-weight font-size text-decoration text-anchor".split(" "));
fabric.Text.DEFAULT_SVG_FONT_SIZE = 16;
fabric.Text.fromElement = function(element, options) {
if (!element) {
return null;
}
var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES);
options = fabric.util.object.extend(options ? fabric.util.object.clone(options) : {}, parsedAttributes);
options.top = options.top || 0;
options.left = options.left || 0;
if ("dx" in parsedAttributes) {
options.left += parsedAttributes.dx;
}
if ("dy" in parsedAttributes) {
options.top += parsedAttributes.dy;
}
if (!("fontSize" in options)) {
options.fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;
}
if (!options.originX) {
options.originX = "left";
}
var textContent = "";
if (!("textContent" in element)) {
if ("firstChild" in element && element.firstChild !== null) {
if ("data" in element.firstChild && element.firstChild.data !== null) {
textContent = element.firstChild.data;
}
}
} else {
textContent = element.textContent;
}
textContent = textContent.replace(/^\s+|\s+$|\n+/g, "").replace(/\s+/g, " ");
var text = new fabric.Text(textContent, options), textHeightScaleFactor = text.getHeight() / text.height, lineHeightDiff = (text.height + text.strokeWidth) * text.lineHeight - text.height, scaledDiff = lineHeightDiff * textHeightScaleFactor, textHeight = text.getHeight() + scaledDiff, offX = 0;
if (text.originX === "left") {
offX = text.getWidth() / 2;
}
if (text.originX === "right") {
offX = -text.getWidth() / 2;
}
text.set({
left: text.getLeft() + offX,
top: text.getTop() - textHeight / 2 + text.fontSize * (.18 + text._fontSizeFraction) / text.lineHeight
});
return text;
};
fabric.Text.fromObject = function(object, callback) {
var text = new fabric.Text(object.text, clone(object));
callback && callback(text);
return text;
};
fabric.util.createAccessors(fabric.Text);
})( true ? exports : this);
(function() {
var clone = fabric.util.object.clone;
fabric.IText = fabric.util.createClass(fabric.Text, fabric.Observable, {
type: "i-text",
selectionStart: 0,
selectionEnd: 0,
selectionColor: "rgba(17,119,255,0.3)",
isEditing: false,
editable: true,
editingBorderColor: "rgba(102,153,255,0.25)",
cursorWidth: 2,
cursorColor: "#333",
cursorDelay: 1e3,
cursorDuration: 600,
styles: null,
caching: true,
_reSpace: /\s|\n/,
_currentCursorOpacity: 0,
_selectionDirection: null,
_abortCursorAnimation: false,
__widthOfSpace: [],
initialize: function(text, options) {
this.styles = options ? options.styles || {} : {};
this.callSuper("initialize", text, options);
this.initBehavior();
},
_clearCache: function() {
this.callSuper("_clearCache");
this.__widthOfSpace = [];
},
isEmptyStyles: function() {
if (!this.styles) {
return true;
}
var obj = this.styles;
for (var p1 in obj) {
for (var p2 in obj[p1]) {
for (var p3 in obj[p1][p2]) {
return false;
}
}
}
return true;
},
setSelectionStart: function(index) {
index = Math.max(index, 0);
this._updateAndFire("selectionStart", index);
},
setSelectionEnd: function(index) {
index = Math.min(index, this.text.length);
this._updateAndFire("selectionEnd", index);
},
_updateAndFire: function(property, index) {
if (this[property] !== index) {
this._fireSelectionChanged();
this[property] = index;
}
this._updateTextarea();
},
_fireSelectionChanged: function() {
this.fire("selection:changed");
this.canvas && this.canvas.fire("text:selection:changed", {
target: this
});
},
getSelectionStyles: function(startIndex, endIndex) {
if (arguments.length === 2) {
var styles = [];
for (var i = startIndex; i < endIndex; i++) {
styles.push(this.getSelectionStyles(i));
}
return styles;
}
var loc = this.get2DCursorLocation(startIndex), style = this._getStyleDeclaration(loc.lineIndex, loc.charIndex);
return style || {};
},
setSelectionStyles: function(styles) {
if (this.selectionStart === this.selectionEnd) {
this._extendStyles(this.selectionStart, styles);
} else {
for (var i = this.selectionStart; i < this.selectionEnd; i++) {
this._extendStyles(i, styles);
}
}
this._forceClearCache = true;
return this;
},
_extendStyles: function(index, styles) {
var loc = this.get2DCursorLocation(index);
if (!this._getLineStyle(loc.lineIndex)) {
this._setLineStyle(loc.lineIndex, {});
}
if (!this._getStyleDeclaration(loc.lineIndex, loc.charIndex)) {
this._setStyleDeclaration(loc.lineIndex, loc.charIndex, {});
}
fabric.util.object.extend(this._getStyleDeclaration(loc.lineIndex, loc.charIndex), styles);
},
render: function(ctx, noTransform) {
this.clearContextTop();
this.callSuper("render", ctx, noTransform);
},
_render: function(ctx) {
this.callSuper("_render", ctx);
this.ctx = ctx;
this.cursorOffsetCache = {};
this.renderCursorOrSelection();
},
clearContextTop: function() {
if (!this.active || !this.isEditing) {
return;
}
if (this.canvas && this.canvas.contextTop) {
var ctx = this.canvas.contextTop;
ctx.save();
ctx.transform.apply(ctx, this.canvas.viewportTransform);
this.transform(ctx);
this.transformMatrix && ctx.transform.apply(ctx, this.transformMatrix);
this._clearTextArea(ctx);
ctx.restore();
}
},
renderCursorOrSelection: function() {
if (!this.active || !this.isEditing) {
return;
}
var chars = this.text.split(""), boundaries, ctx;
if (this.canvas && this.canvas.contextTop) {
ctx = this.canvas.contextTop;
ctx.save();
ctx.transform.apply(ctx, this.canvas.viewportTransform);
this.transform(ctx);
this.transformMatrix && ctx.transform.apply(ctx, this.transformMatrix);
this._clearTextArea(ctx);
} else {
ctx = this.ctx;
ctx.save();
}
if (this.selectionStart === this.selectionEnd) {
boundaries = this._getCursorBoundaries(chars, "cursor");
this.renderCursor(boundaries, ctx);
} else {
boundaries = this._getCursorBoundaries(chars, "selection");
this.renderSelection(chars, boundaries, ctx);
}
ctx.restore();
},
_clearTextArea: function(ctx) {
var width = this.width + 4, height = this.height + 4;
ctx.clearRect(-width / 2, -height / 2, width, height);
},
get2DCursorLocation: function(selectionStart) {
if (typeof selectionStart === "undefined") {
selectionStart = this.selectionStart;
}
var len = this._textLines.length;
for (var i = 0; i < len; i++) {
if (selectionStart <= this._textLines[i].length) {
return {
lineIndex: i,
charIndex: selectionStart
};
}
selectionStart -= this._textLines[i].length + 1;
}
return {
lineIndex: i - 1,
charIndex: this._textLines[i - 1].length < selectionStart ? this._textLines[i - 1].length : selectionStart
};
},
getCurrentCharStyle: function(lineIndex, charIndex) {
var style = this._getStyleDeclaration(lineIndex, charIndex === 0 ? 0 : charIndex - 1);
return {
fontSize: style && style.fontSize || this.fontSize,
fill: style && style.fill || this.fill,
textBackgroundColor: style && style.textBackgroundColor || this.textBackgroundColor,
textDecoration: style && style.textDecoration || this.textDecoration,
fontFamily: style && style.fontFamily || this.fontFamily,
fontWeight: style && style.fontWeight || this.fontWeight,
fontStyle: style && style.fontStyle || this.fontStyle,
stroke: style && style.stroke || this.stroke,
strokeWidth: style && style.strokeWidth || this.strokeWidth
};
},
getCurrentCharFontSize: function(lineIndex, charIndex) {
var style = this._getStyleDeclaration(lineIndex, charIndex === 0 ? 0 : charIndex - 1);
return style && style.fontSize ? style.fontSize : this.fontSize;
},
getCurrentCharColor: function(lineIndex, charIndex) {
var style = this._getStyleDeclaration(lineIndex, charIndex === 0 ? 0 : charIndex - 1);
return style && style.fill ? style.fill : this.cursorColor;
},
_getCursorBoundaries: function(chars, typeOfBoundaries) {
var left = Math.round(this._getLeftOffset()), top = this._getTopOffset(), offsets = this._getCursorBoundariesOffsets(chars, typeOfBoundaries);
return {
left: left,
top: top,
leftOffset: offsets.left + offsets.lineLeft,
topOffset: offsets.top
};
},
_getCursorBoundariesOffsets: function(chars, typeOfBoundaries) {
if (this.cursorOffsetCache && "top" in this.cursorOffsetCache) {
return this.cursorOffsetCache;
}
var lineLeftOffset = 0, lineIndex = 0, charIndex = 0, topOffset = 0, leftOffset = 0, boundaries;
for (var i = 0; i < this.selectionStart; i++) {
if (chars[i] === "\n") {
leftOffset = 0;
topOffset += this._getHeightOfLine(this.ctx, lineIndex);
lineIndex++;
charIndex = 0;
} else {
leftOffset += this._getWidthOfChar(this.ctx, chars[i], lineIndex, charIndex);
charIndex++;
}
lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(this.ctx, lineIndex));
}
if (typeOfBoundaries === "cursor") {
topOffset += (1 - this._fontSizeFraction) * this._getHeightOfLine(this.ctx, lineIndex) / this.lineHeight - this.getCurrentCharFontSize(lineIndex, charIndex) * (1 - this._fontSizeFraction);
}
if (this.charSpacing !== 0 && charIndex === this._textLines[lineIndex].length) {
leftOffset -= this._getWidthOfCharSpacing();
}
boundaries = {
top: topOffset,
left: leftOffset > 0 ? leftOffset : 0,
lineLeft: lineLeftOffset
};
this.cursorOffsetCache = boundaries;
return this.cursorOffsetCache;
},
renderCursor: function(boundaries, ctx) {
var cursorLocation = this.get2DCursorLocation(), lineIndex = cursorLocation.lineIndex, charIndex = cursorLocation.charIndex, charHeight = this.getCurrentCharFontSize(lineIndex, charIndex), leftOffset = lineIndex === 0 && charIndex === 0 ? this._getLineLeftOffset(this._getLineWidth(ctx, lineIndex)) : boundaries.leftOffset, multiplier = this.scaleX * this.canvas.getZoom(), cursorWidth = this.cursorWidth / multiplier;
ctx.fillStyle = this.getCurrentCharColor(lineIndex, charIndex);
ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity;
ctx.fillRect(boundaries.left + leftOffset - cursorWidth / 2, boundaries.top + boundaries.topOffset, cursorWidth, charHeight);
},
renderSelection: function(chars, boundaries, ctx) {
ctx.fillStyle = this.selectionColor;
var start = this.get2DCursorLocation(this.selectionStart), end = this.get2DCursorLocation(this.selectionEnd), startLine = start.lineIndex, endLine = end.lineIndex;
for (var i = startLine; i <= endLine; i++) {
var lineOffset = this._getLineLeftOffset(this._getLineWidth(ctx, i)) || 0, lineHeight = this._getHeightOfLine(this.ctx, i), realLineHeight = 0, boxWidth = 0, line = this._textLines[i];
if (i === startLine) {
for (var j = 0, len = line.length; j < len; j++) {
if (j >= start.charIndex && (i !== endLine || j < end.charIndex)) {
boxWidth += this._getWidthOfChar(ctx, line[j], i, j);
}
if (j < start.charIndex) {
lineOffset += this._getWidthOfChar(ctx, line[j], i, j);
}
}
if (j === line.length) {
boxWidth -= this._getWidthOfCharSpacing();
}
} else if (i > startLine && i < endLine) {
boxWidth += this._getLineWidth(ctx, i) || 5;
} else if (i === endLine) {
for (var j2 = 0, j2len = end.charIndex; j2 < j2len; j2++) {
boxWidth += this._getWidthOfChar(ctx, line[j2], i, j2);
}
if (end.charIndex === line.length) {
boxWidth -= this._getWidthOfCharSpacing();
}
}
realLineHeight = lineHeight;
if (this.lineHeight < 1 || i === endLine && this.lineHeight > 1) {
lineHeight /= this.lineHeight;
}
ctx.fillRect(boundaries.left + lineOffset, boundaries.top + boundaries.topOffset, boxWidth > 0 ? boxWidth : 0, lineHeight);
boundaries.topOffset += realLineHeight;
}
},
_renderChars: function(method, ctx, line, left, top, lineIndex, charOffset) {
if (this.isEmptyStyles()) {
return this._renderCharsFast(method, ctx, line, left, top);
}
charOffset = charOffset || 0;
var lineHeight = this._getHeightOfLine(ctx, lineIndex), prevStyle, thisStyle, charsToRender = "";
ctx.save();
top -= lineHeight / this.lineHeight * this._fontSizeFraction;
for (var i = charOffset, len = line.length + charOffset; i <= len; i++) {
prevStyle = prevStyle || this.getCurrentCharStyle(lineIndex, i);
thisStyle = this.getCurrentCharStyle(lineIndex, i + 1);
if (this._hasStyleChanged(prevStyle, thisStyle) || i === len) {
this._renderChar(method, ctx, lineIndex, i - 1, charsToRender, left, top, lineHeight);
charsToRender = "";
prevStyle = thisStyle;
}
charsToRender += line[i - charOffset];
}
ctx.restore();
},
_renderCharsFast: function(method, ctx, line, left, top) {
if (method === "fillText" && this.fill) {
this.callSuper("_renderChars", method, ctx, line, left, top);
}
if (method === "strokeText" && (this.stroke && this.strokeWidth > 0 || this.skipFillStrokeCheck)) {
this.callSuper("_renderChars", method, ctx, line, left, top);
}
},
_renderChar: function(method, ctx, lineIndex, i, _char, left, top, lineHeight) {
var charWidth, charHeight, shouldFill, shouldStroke, decl = this._getStyleDeclaration(lineIndex, i), offset, textDecoration, chars, additionalSpace, _charWidth;
if (decl) {
charHeight = this._getHeightOfChar(ctx, _char, lineIndex, i);
shouldStroke = decl.stroke;
shouldFill = decl.fill;
textDecoration = decl.textDecoration;
} else {
charHeight = this.fontSize;
}
shouldStroke = (shouldStroke || this.stroke) && method === "strokeText";
shouldFill = (shouldFill || this.fill) && method === "fillText";
decl && ctx.save();
charWidth = this._applyCharStylesGetWidth(ctx, _char, lineIndex, i, decl || null);
textDecoration = textDecoration || this.textDecoration;
if (decl && decl.textBackgroundColor) {
this._removeShadow(ctx);
}
if (this.charSpacing !== 0) {
additionalSpace = this._getWidthOfCharSpacing();
chars = _char.split("");
charWidth = 0;
for (var j = 0, len = chars.length, char; j < len; j++) {
char = chars[j];
shouldFill && ctx.fillText(char, left + charWidth, top);
shouldStroke && ctx.strokeText(char, left + charWidth, top);
_charWidth = ctx.measureText(char).width + additionalSpace;
charWidth += _charWidth > 0 ? _charWidth : 0;
}
} else {
shouldFill && ctx.fillText(_char, left, top);
shouldStroke && ctx.strokeText(_char, left, top);
}
if (textDecoration || textDecoration !== "") {
offset = this._fontSizeFraction * lineHeight / this.lineHeight;
this._renderCharDecoration(ctx, textDecoration, left, top, offset, charWidth, charHeight);
}
decl && ctx.restore();
ctx.translate(charWidth, 0);
},
_hasStyleChanged: function(prevStyle, thisStyle) {
return prevStyle.fill !== thisStyle.fill || prevStyle.fontSize !== thisStyle.fontSize || prevStyle.textBackgroundColor !== thisStyle.textBackgroundColor || prevStyle.textDecoration !== thisStyle.textDecoration || prevStyle.fontFamily !== thisStyle.fontFamily || prevStyle.fontWeight !== thisStyle.fontWeight || prevStyle.fontStyle !== thisStyle.fontStyle || prevStyle.stroke !== thisStyle.stroke || prevStyle.strokeWidth !== thisStyle.strokeWidth;
},
_renderCharDecoration: function(ctx, textDecoration, left, top, offset, charWidth, charHeight) {
if (!textDecoration) {
return;
}
var decorationWeight = charHeight / 15, positions = {
underline: top + charHeight / 10,
"line-through": top - charHeight * (this._fontSizeFraction + this._fontSizeMult - 1) + decorationWeight,
overline: top - (this._fontSizeMult - this._fontSizeFraction) * charHeight
}, decorations = [ "underline", "line-through", "overline" ], i, decoration;
for (i = 0; i < decorations.length; i++) {
decoration = decorations[i];
if (textDecoration.indexOf(decoration) > -1) {
ctx.fillRect(left, positions[decoration], charWidth, decorationWeight);
}
}
},
_renderTextLine: function(method, ctx, line, left, top, lineIndex) {
if (!this.isEmptyStyles()) {
top += this.fontSize * (this._fontSizeFraction + .03);
}
this.callSuper("_renderTextLine", method, ctx, line, left, top, lineIndex);
},
_renderTextDecoration: function(ctx) {
if (this.isEmptyStyles()) {
return this.callSuper("_renderTextDecoration", ctx);
}
},
_renderTextLinesBackground: function(ctx) {
this.callSuper("_renderTextLinesBackground", ctx);
var lineTopOffset = 0, heightOfLine, lineWidth, lineLeftOffset, leftOffset = this._getLeftOffset(), topOffset = this._getTopOffset(), line, _char, style;
for (var i = 0, len = this._textLines.length; i < len; i++) {
heightOfLine = this._getHeightOfLine(ctx, i);
line = this._textLines[i];
if (line === "" || !this.styles || !this._getLineStyle(i)) {
lineTopOffset += heightOfLine;
continue;
}
lineWidth = this._getLineWidth(ctx, i);
lineLeftOffset = this._getLineLeftOffset(lineWidth);
for (var j = 0, jlen = line.length; j < jlen; j++) {
style = this._getStyleDeclaration(i, j);
if (!style || !style.textBackgroundColor) {
continue;
}
_char = line[j];
ctx.fillStyle = style.textBackgroundColor;
ctx.fillRect(leftOffset + lineLeftOffset + this._getWidthOfCharsAt(ctx, i, j), topOffset + lineTopOffset, this._getWidthOfChar(ctx, _char, i, j), heightOfLine / this.lineHeight);
}
lineTopOffset += heightOfLine;
}
},
_getCacheProp: function(_char, styleDeclaration) {
return _char + styleDeclaration.fontSize + styleDeclaration.fontWeight + styleDeclaration.fontStyle;
},
_getFontCache: function(fontFamily) {
if (!fabric.charWidthsCache[fontFamily]) {
fabric.charWidthsCache[fontFamily] = {};
}
return fabric.charWidthsCache[fontFamily];
},
_applyCharStylesGetWidth: function(ctx, _char, lineIndex, charIndex, decl) {
var charDecl = decl || this._getStyleDeclaration(lineIndex, charIndex), styleDeclaration = clone(charDecl), width, cacheProp, charWidthsCache;
this._applyFontStyles(styleDeclaration);
charWidthsCache = this._getFontCache(styleDeclaration.fontFamily);
cacheProp = this._getCacheProp(_char, styleDeclaration);
if (!charDecl && charWidthsCache[cacheProp] && this.caching) {
return charWidthsCache[cacheProp];
}
if (typeof styleDeclaration.shadow === "string") {
styleDeclaration.shadow = new fabric.Shadow(styleDeclaration.shadow);
}
var fill = styleDeclaration.fill || this.fill;
ctx.fillStyle = fill.toLive ? fill.toLive(ctx, this) : fill;
if (styleDeclaration.stroke) {
ctx.strokeStyle = styleDeclaration.stroke && styleDeclaration.stroke.toLive ? styleDeclaration.stroke.toLive(ctx, this) : styleDeclaration.stroke;
}
ctx.lineWidth = styleDeclaration.strokeWidth || this.strokeWidth;
ctx.font = this._getFontDeclaration.call(styleDeclaration);
if (styleDeclaration.shadow) {
styleDeclaration.scaleX = this.scaleX;
styleDeclaration.scaleY = this.scaleY;
styleDeclaration.canvas = this.canvas;
styleDeclaration.getObjectScaling = this.getObjectScaling;
this._setShadow.call(styleDeclaration, ctx);
}
if (!this.caching || !charWidthsCache[cacheProp]) {
width = ctx.measureText(_char).width;
this.caching && (charWidthsCache[cacheProp] = width);
return width;
}
return charWidthsCache[cacheProp];
},
_applyFontStyles: function(styleDeclaration) {
if (!styleDeclaration.fontFamily) {
styleDeclaration.fontFamily = this.fontFamily;
}
if (!styleDeclaration.fontSize) {
styleDeclaration.fontSize = this.fontSize;
}
if (!styleDeclaration.fontWeight) {
styleDeclaration.fontWeight = this.fontWeight;
}
if (!styleDeclaration.fontStyle) {
styleDeclaration.fontStyle = this.fontStyle;
}
},
_getStyleDeclaration: function(lineIndex, charIndex, returnCloneOrEmpty) {
if (returnCloneOrEmpty) {
return this.styles[lineIndex] && this.styles[lineIndex][charIndex] ? clone(this.styles[lineIndex][charIndex]) : {};
}
return this.styles[lineIndex] && this.styles[lineIndex][charIndex] ? this.styles[lineIndex][charIndex] : null;
},
_setStyleDeclaration: function(lineIndex, charIndex, style) {
this.styles[lineIndex][charIndex] = style;
},
_deleteStyleDeclaration: function(lineIndex, charIndex) {
delete this.styles[lineIndex][charIndex];
},
_getLineStyle: function(lineIndex) {
return this.styles[lineIndex];
},
_setLineStyle: function(lineIndex, style) {
this.styles[lineIndex] = style;
},
_deleteLineStyle: function(lineIndex) {
delete this.styles[lineIndex];
},
_getWidthOfChar: function(ctx, _char, lineIndex, charIndex) {
if (!this._isMeasuring && this.textAlign === "justify" && this._reSpacesAndTabs.test(_char)) {
return this._getWidthOfSpace(ctx, lineIndex);
}
ctx.save();
var width = this._applyCharStylesGetWidth(ctx, _char, lineIndex, charIndex);
if (this.charSpacing !== 0) {
width += this._getWidthOfCharSpacing();
}
ctx.restore();
return width > 0 ? width : 0;
},
_getHeightOfChar: function(ctx, lineIndex, charIndex) {
var style = this._getStyleDeclaration(lineIndex, charIndex);
return style && style.fontSize ? style.fontSize : this.fontSize;
},
_getWidthOfCharsAt: function(ctx, lineIndex, charIndex) {
var width = 0, i, _char;
for (i = 0; i < charIndex; i++) {
_char = this._textLines[lineIndex][i];
width += this._getWidthOfChar(ctx, _char, lineIndex, i);
}
return width;
},
_measureLine: function(ctx, lineIndex) {
this._isMeasuring = true;
var width = this._getWidthOfCharsAt(ctx, lineIndex, this._textLines[lineIndex].length);
if (this.charSpacing !== 0) {
width -= this._getWidthOfCharSpacing();
}
this._isMeasuring = false;
return width > 0 ? width : 0;
},
_getWidthOfSpace: function(ctx, lineIndex) {
if (this.__widthOfSpace[lineIndex]) {
return this.__widthOfSpace[lineIndex];
}
var line = this._textLines[lineIndex], wordsWidth = this._getWidthOfWords(ctx, line, lineIndex, 0), widthDiff = this.width - wordsWidth, numSpaces = line.length - line.replace(this._reSpacesAndTabs, "").length, width = Math.max(widthDiff / numSpaces, ctx.measureText(" ").width);
this.__widthOfSpace[lineIndex] = width;
return width;
},
_getWidthOfWords: function(ctx, line, lineIndex, charOffset) {
var width = 0;
for (var charIndex = 0; charIndex < line.length; charIndex++) {
var _char = line[charIndex];
if (!_char.match(/\s/)) {
width += this._getWidthOfChar(ctx, _char, lineIndex, charIndex + charOffset);
}
}
return width;
},
_getHeightOfLine: function(ctx, lineIndex) {
if (this.__lineHeights[lineIndex]) {
return this.__lineHeights[lineIndex];
}
var line = this._textLines[lineIndex], maxHeight = this._getHeightOfChar(ctx, lineIndex, 0);
for (var i = 1, len = line.length; i < len; i++) {
var currentCharHeight = this._getHeightOfChar(ctx, lineIndex, i);
if (currentCharHeight > maxHeight) {
maxHeight = currentCharHeight;
}
}
this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult;
return this.__lineHeights[lineIndex];
},
_getTextHeight: function(ctx) {
var lineHeight, height = 0;
for (var i = 0, len = this._textLines.length; i < len; i++) {
lineHeight = this._getHeightOfLine(ctx, i);
height += i === len - 1 ? lineHeight / this.lineHeight : lineHeight;
}
return height;
},
toObject: function(propertiesToInclude) {
return fabric.util.object.extend(this.callSuper("toObject", propertiesToInclude), {
styles: clone(this.styles, true)
});
}
});
fabric.IText.fromObject = function(object, callback) {
var iText = new fabric.IText(object.text, clone(object));
callback && callback(iText);
return iText;
};
})();
(function() {
var clone = fabric.util.object.clone;
fabric.util.object.extend(fabric.IText.prototype, {
initBehavior: function() {
this.initAddedHandler();
this.initRemovedHandler();
this.initCursorSelectionHandlers();
this.initDoubleClickSimulation();
this.mouseMoveHandler = this.mouseMoveHandler.bind(this);
},
initSelectedHandler: function() {
this.on("selected", function() {
var _this = this;
setTimeout(function() {
_this.selected = true;
}, 100);
});
},
initAddedHandler: function() {
var _this = this;
this.on("added", function() {
var canvas = _this.canvas;
if (canvas) {
if (!canvas._hasITextHandlers) {
canvas._hasITextHandlers = true;
_this._initCanvasHandlers(canvas);
}
canvas._iTextInstances = canvas._iTextInstances || [];
canvas._iTextInstances.push(_this);
}
});
},
initRemovedHandler: function() {
var _this = this;
this.on("removed", function() {
var canvas = _this.canvas;
if (canvas) {
canvas._iTextInstances = canvas._iTextInstances || [];
fabric.util.removeFromArray(canvas._iTextInstances, _this);
if (canvas._iTextInstances.length === 0) {
canvas._hasITextHandlers = false;
_this._removeCanvasHandlers(canvas);
}
}
});
},
_initCanvasHandlers: function(canvas) {
canvas._canvasITextSelectionClearedHanlder = function() {
fabric.IText.prototype.exitEditingOnOthers(canvas);
}.bind(this);
canvas._mouseUpITextHandler = function() {
if (canvas._iTextInstances) {
canvas._iTextInstances.forEach(function(obj) {
obj.__isMousedown = false;
});
}
}.bind(this);
canvas.on("selection:cleared", canvas._canvasITextSelectionClearedHanlder);
canvas.on("object:selected", canvas._canvasITextSelectionClearedHanlder);
canvas.on("mouse:up", canvas._mouseUpITextHandler);
},
_removeCanvasHandlers: function(canvas) {
canvas.off("selection:cleared", canvas._canvasITextSelectionClearedHanlder);
canvas.off("object:selected", canvas._canvasITextSelectionClearedHanlder);
canvas.off("mouse:up", canvas._mouseUpITextHandler);
},
_tick: function() {
this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, "_onTickComplete");
},
_animateCursor: function(obj, targetOpacity, duration, completeMethod) {
var tickState;
tickState = {
isAborted: false,
abort: function() {
this.isAborted = true;
}
};
obj.animate("_currentCursorOpacity", targetOpacity, {
duration: duration,
onComplete: function() {
if (!tickState.isAborted) {
obj[completeMethod]();
}
},
onChange: function() {
if (obj.canvas && obj.selectionStart === obj.selectionEnd) {
obj.renderCursorOrSelection();
}
},
abort: function() {
return tickState.isAborted;
}
});
return tickState;
},
_onTickComplete: function() {
var _this = this;
if (this._cursorTimeout1) {
clearTimeout(this._cursorTimeout1);
}
this._cursorTimeout1 = setTimeout(function() {
_this._currentTickCompleteState = _this._animateCursor(_this, 0, this.cursorDuration / 2, "_tick");
}, 100);
},
initDelayedCursor: function(restart) {
var _this = this, delay = restart ? 0 : this.cursorDelay;
this.abortCursorAnimation();
this._currentCursorOpacity = 1;
this._cursorTimeout2 = setTimeout(function() {
_this._tick();
}, delay);
},
abortCursorAnimation: function() {
var shouldClear = this._currentTickState || this._currentTickCompleteState;
this._currentTickState && this._currentTickState.abort();
this._currentTickCompleteState && this._currentTickCompleteState.abort();
clearTimeout(this._cursorTimeout1);
clearTimeout(this._cursorTimeout2);
this._currentCursorOpacity = 0;
if (shouldClear) {
this.canvas && this.canvas.clearContext(this.canvas.contextTop || this.ctx);
}
},
selectAll: function() {
this.selectionStart = 0;
this.selectionEnd = this.text.length;
this._fireSelectionChanged();
this._updateTextarea();
},
getSelectedText: function() {
return this.text.slice(this.selectionStart, this.selectionEnd);
},
findWordBoundaryLeft: function(startFrom) {
var offset = 0, index = startFrom - 1;
if (this._reSpace.test(this.text.charAt(index))) {
while (this._reSpace.test(this.text.charAt(index))) {
offset++;
index--;
}
}
while (/\S/.test(this.text.charAt(index)) && index > -1) {
offset++;
index--;
}
return startFrom - offset;
},
findWordBoundaryRight: function(startFrom) {
var offset = 0, index = startFrom;
if (this._reSpace.test(this.text.charAt(index))) {
while (this._reSpace.test(this.text.charAt(index))) {
offset++;
index++;
}
}
while (/\S/.test(this.text.charAt(index)) && index < this.text.length) {
offset++;
index++;
}
return startFrom + offset;
},
findLineBoundaryLeft: function(startFrom) {
var offset = 0, index = startFrom - 1;
while (!/\n/.test(this.text.charAt(index)) && index > -1) {
offset++;
index--;
}
return startFrom - offset;
},
findLineBoundaryRight: function(startFrom) {
var offset = 0, index = startFrom;
while (!/\n/.test(this.text.charAt(index)) && index < this.text.length) {
offset++;
index++;
}
return startFrom + offset;
},
getNumNewLinesInSelectedText: function() {
var selectedText = this.getSelectedText(), numNewLines = 0;
for (var i = 0, len = selectedText.length; i < len; i++) {
if (selectedText[i] === "\n") {
numNewLines++;
}
}
return numNewLines;
},
searchWordBoundary: function(selectionStart, direction) {
var index = this._reSpace.test(this.text.charAt(selectionStart)) ? selectionStart - 1 : selectionStart, _char = this.text.charAt(index), reNonWord = /[ \n\.,;!\?\-]/;
while (!reNonWord.test(_char) && index > 0 && index < this.text.length) {
index += direction;
_char = this.text.charAt(index);
}
if (reNonWord.test(_char) && _char !== "\n") {
index += direction === 1 ? 0 : 1;
}
return index;
},
selectWord: function(selectionStart) {
selectionStart = selectionStart || this.selectionStart;
var newSelectionStart = this.searchWordBoundary(selectionStart, -1), newSelectionEnd = this.searchWordBoundary(selectionStart, 1);
this.selectionStart = newSelectionStart;
this.selectionEnd = newSelectionEnd;
this._fireSelectionChanged();
this._updateTextarea();
this.renderCursorOrSelection();
},
selectLine: function(selectionStart) {
selectionStart = selectionStart || this.selectionStart;
var newSelectionStart = this.findLineBoundaryLeft(selectionStart), newSelectionEnd = this.findLineBoundaryRight(selectionStart);
this.selectionStart = newSelectionStart;
this.selectionEnd = newSelectionEnd;
this._fireSelectionChanged();
this._updateTextarea();
},
enterEditing: function(e) {
if (this.isEditing || !this.editable) {
return;
}
if (this.canvas) {
this.exitEditingOnOthers(this.canvas);
}
this.isEditing = true;
this.initHiddenTextarea(e);
this.hiddenTextarea.focus();
this._updateTextarea();
this._saveEditingProps();
this._setEditingProps();
this._textBeforeEdit = this.text;
this._tick();
this.fire("editing:entered");
if (!this.canvas) {
return this;
}
this.canvas.fire("text:editing:entered", {
target: this
});
this.initMouseMoveHandler();
this.canvas.renderAll();
return this;
},
exitEditingOnOthers: function(canvas) {
if (canvas._iTextInstances) {
canvas._iTextInstances.forEach(function(obj) {
obj.selected = false;
if (obj.isEditing) {
obj.exitEditing();
}
});
}
},
initMouseMoveHandler: function() {
this.canvas.on("mouse:move", this.mouseMoveHandler);
},
mouseMoveHandler: function(options) {
if (!this.__isMousedown || !this.isEditing) {
return;
}
var newSelectionStart = this.getSelectionStartFromPointer(options.e), currentStart = this.selectionStart, currentEnd = this.selectionEnd;
if (newSelectionStart === this.__selectionStartOnMouseDown) {
return;
}
if (newSelectionStart > this.__selectionStartOnMouseDown) {
this.selectionStart = this.__selectionStartOnMouseDown;
this.selectionEnd = newSelectionStart;
} else {
this.selectionStart = newSelectionStart;
this.selectionEnd = this.__selectionStartOnMouseDown;
}
if (this.selectionStart !== currentStart || this.selectionEnd !== currentEnd) {
this._fireSelectionChanged();
this._updateTextarea();
this.renderCursorOrSelection();
}
},
_setEditingProps: function() {
this.hoverCursor = "text";
if (this.canvas) {
this.canvas.defaultCursor = this.canvas.moveCursor = "text";
}
this.borderColor = this.editingBorderColor;
this.hasControls = this.selectable = false;
this.lockMovementX = this.lockMovementY = true;
},
_updateTextarea: function() {
if (!this.hiddenTextarea || this.inCompositionMode) {
return;
}
this.cursorOffsetCache = {};
this.hiddenTextarea.value = this.text;
this.hiddenTextarea.selectionStart = this.selectionStart;
this.hiddenTextarea.selectionEnd = this.selectionEnd;
if (this.selectionStart === this.selectionEnd) {
var style = this._calcTextareaPosition();
this.hiddenTextarea.style.left = style.left;
this.hiddenTextarea.style.top = style.top;
this.hiddenTextarea.style.fontSize = style.fontSize;
}
},
_calcTextareaPosition: function() {
if (!this.canvas) {
return {
x: 1,
y: 1
};
}
var chars = this.text.split(""), boundaries = this._getCursorBoundaries(chars, "cursor"), cursorLocation = this.get2DCursorLocation(), lineIndex = cursorLocation.lineIndex, charIndex = cursorLocation.charIndex, charHeight = this.getCurrentCharFontSize(lineIndex, charIndex), leftOffset = lineIndex === 0 && charIndex === 0 ? this._getLineLeftOffset(this._getLineWidth(this.ctx, lineIndex)) : boundaries.leftOffset, m = this.calcTransformMatrix(), p = {
x: boundaries.left + leftOffset,
y: boundaries.top + boundaries.topOffset + charHeight
}, upperCanvas = this.canvas.upperCanvasEl, maxWidth = upperCanvas.width - charHeight, maxHeight = upperCanvas.height - charHeight;
p = fabric.util.transformPoint(p, m);
p = fabric.util.transformPoint(p, this.canvas.viewportTransform);
if (p.x < 0) {
p.x = 0;
}
if (p.x > maxWidth) {
p.x = maxWidth;
}
if (p.y < 0) {
p.y = 0;
}
if (p.y > maxHeight) {
p.y = maxHeight;
}
p.x += this.canvas._offset.left;
p.y += this.canvas._offset.top;
return {
left: p.x + "px",
top: p.y + "px",
fontSize: charHeight
};
},
_saveEditingProps: function() {
this._savedProps = {
hasControls: this.hasControls,
borderColor: this.borderColor,
lockMovementX: this.lockMovementX,
lockMovementY: this.lockMovementY,
hoverCursor: this.hoverCursor,
defaultCursor: this.canvas && this.canvas.defaultCursor,
moveCursor: this.canvas && this.canvas.moveCursor
};
},
_restoreEditingProps: function() {
if (!this._savedProps) {
return;
}
this.hoverCursor = this._savedProps.overCursor;
this.hasControls = this._savedProps.hasControls;
this.borderColor = this._savedProps.borderColor;
this.lockMovementX = this._savedProps.lockMovementX;
this.lockMovementY = this._savedProps.lockMovementY;
if (this.canvas) {
this.canvas.defaultCursor = this._savedProps.defaultCursor;
this.canvas.moveCursor = this._savedProps.moveCursor;
}
},
exitEditing: function() {
var isTextChanged = this._textBeforeEdit !== this.text;
this.selected = false;
this.isEditing = false;
this.selectable = true;
this.selectionEnd = this.selectionStart;
this.hiddenTextarea && this.canvas && this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea);
this.hiddenTextarea = null;
this.abortCursorAnimation();
this._restoreEditingProps();
this._currentCursorOpacity = 0;
this.fire("editing:exited");
isTextChanged && this.fire("modified");
if (this.canvas) {
this.canvas.off("mouse:move", this.mouseMoveHandler);
this.canvas.fire("text:editing:exited", {
target: this
});
isTextChanged && this.canvas.fire("object:modified", {
target: this
});
}
return this;
},
_removeExtraneousStyles: function() {
for (var prop in this.styles) {
if (!this._textLines[prop]) {
delete this.styles[prop];
}
}
},
_removeCharsFromTo: function(start, end) {
while (end !== start) {
this._removeSingleCharAndStyle(start + 1);
end--;
}
this.selectionStart = start;
this.selectionEnd = start;
},
_removeSingleCharAndStyle: function(index) {
var isBeginningOfLine = this.text[index - 1] === "\n", indexStyle = isBeginningOfLine ? index : index - 1;
this.removeStyleObject(isBeginningOfLine, indexStyle);
this.text = this.text.slice(0, index - 1) + this.text.slice(index);
this._textLines = this._splitTextIntoLines();
},
insertChars: function(_chars, useCopiedStyle) {
var style;
if (this.selectionEnd - this.selectionStart > 1) {
this._removeCharsFromTo(this.selectionStart, this.selectionEnd);
}
if (!useCopiedStyle && this.isEmptyStyles()) {
this.insertChar(_chars, false);
return;
}
for (var i = 0, len = _chars.length; i < len; i++) {
if (useCopiedStyle) {
style = fabric.copiedTextStyle[i];
}
this.insertChar(_chars[i], i < len - 1, style);
}
},
insertChar: function(_char, skipUpdate, styleObject) {
var isEndOfLine = this.text[this.selectionStart] === "\n";
this.text = this.text.slice(0, this.selectionStart) + _char + this.text.slice(this.selectionEnd);
this._textLines = this._splitTextIntoLines();
this.insertStyleObjects(_char, isEndOfLine, styleObject);
this.selectionStart += _char.length;
this.selectionEnd = this.selectionStart;
if (skipUpdate) {
return;
}
this._updateTextarea();
this.setCoords();
this._fireSelectionChanged();
this.fire("changed");
this.canvas && this.canvas.fire("text:changed", {
target: this
});
this.canvas && this.canvas.renderAll();
},
insertNewlineStyleObject: function(lineIndex, charIndex, isEndOfLine) {
this.shiftLineStyles(lineIndex, +1);
if (!this.styles[lineIndex + 1]) {
this.styles[lineIndex + 1] = {};
}
var currentCharStyle = {}, newLineStyles = {};
if (this.styles[lineIndex] && this.styles[lineIndex][charIndex - 1]) {
currentCharStyle = this.styles[lineIndex][charIndex - 1];
}
if (isEndOfLine) {
newLineStyles[0] = clone(currentCharStyle);
this.styles[lineIndex + 1] = newLineStyles;
} else {
for (var index in this.styles[lineIndex]) {
if (parseInt(index, 10) >= charIndex) {
newLineStyles[parseInt(index, 10) - charIndex] = this.styles[lineIndex][index];
delete this.styles[lineIndex][index];
}
}
this.styles[lineIndex + 1] = newLineStyles;
}
this._forceClearCache = true;
},
insertCharStyleObject: function(lineIndex, charIndex, style) {
var currentLineStyles = this.styles[lineIndex], currentLineStylesCloned = clone(currentLineStyles);
if (charIndex === 0 && !style) {
charIndex = 1;
}
for (var index in currentLineStylesCloned) {
var numericIndex = parseInt(index, 10);
if (numericIndex >= charIndex) {
currentLineStyles[numericIndex + 1] = currentLineStylesCloned[numericIndex];
if (!currentLineStylesCloned[numericIndex - 1]) {
delete currentLineStyles[numericIndex];
}
}
}
this.styles[lineIndex][charIndex] = style || clone(currentLineStyles[charIndex - 1]);
this._forceClearCache = true;
},
insertStyleObjects: function(_chars, isEndOfLine, styleObject) {
var cursorLocation = this.get2DCursorLocation(), lineIndex = cursorLocation.lineIndex, charIndex = cursorLocation.charIndex;
if (!this._getLineStyle(lineIndex)) {
this._setLineStyle(lineIndex, {});
}
if (_chars === "\n") {
this.insertNewlineStyleObject(lineIndex, charIndex, isEndOfLine);
} else {
this.insertCharStyleObject(lineIndex, charIndex, styleObject);
}
},
shiftLineStyles: function(lineIndex, offset) {
var clonedStyles = clone(this.styles);
for (var line in this.styles) {
var numericLine = parseInt(line, 10);
if (numericLine > lineIndex) {
this.styles[numericLine + offset] = clonedStyles[numericLine];
if (!clonedStyles[numericLine - offset]) {
delete this.styles[numericLine];
}
}
}
},
removeStyleObject: function(isBeginningOfLine, index) {
var cursorLocation = this.get2DCursorLocation(index), lineIndex = cursorLocation.lineIndex, charIndex = cursorLocation.charIndex;
this._removeStyleObject(isBeginningOfLine, cursorLocation, lineIndex, charIndex);
},
_getTextOnPreviousLine: function(lIndex) {
return this._textLines[lIndex - 1];
},
_removeStyleObject: function(isBeginningOfLine, cursorLocation, lineIndex, charIndex) {
if (isBeginningOfLine) {
var textOnPreviousLine = this._getTextOnPreviousLine(cursorLocation.lineIndex), newCharIndexOnPrevLine = textOnPreviousLine ? textOnPreviousLine.length : 0;
if (!this.styles[lineIndex - 1]) {
this.styles[lineIndex - 1] = {};
}
for (charIndex in this.styles[lineIndex]) {
this.styles[lineIndex - 1][parseInt(charIndex, 10) + newCharIndexOnPrevLine] = this.styles[lineIndex][charIndex];
}
this.shiftLineStyles(cursorLocation.lineIndex, -1);
} else {
var currentLineStyles = this.styles[lineIndex];
if (currentLineStyles) {
delete currentLineStyles[charIndex];
}
var currentLineStylesCloned = clone(currentLineStyles);
for (var i in currentLineStylesCloned) {
var numericIndex = parseInt(i, 10);
if (numericIndex >= charIndex && numericIndex !== 0) {
currentLineStyles[numericIndex - 1] = currentLineStylesCloned[numericIndex];
delete currentLineStyles[numericIndex];
}
}
}
},
insertNewline: function() {
this.insertChars("\n");
},
setSelectionStartEndWithShift: function(start, end, newSelection) {
if (newSelection <= start) {
if (end === start) {
this._selectionDirection = "left";
} else if (this._selectionDirection === "right") {
this._selectionDirection = "left";
this.selectionEnd = start;
}
this.selectionStart = newSelection;
} else if (newSelection > start && newSelection < end) {
if (this._selectionDirection === "right") {
this.selectionEnd = newSelection;
} else {
this.selectionStart = newSelection;
}
} else {
if (end === start) {
this._selectionDirection = "right";
} else if (this._selectionDirection === "left") {
this._selectionDirection = "right";
this.selectionStart = end;
}
this.selectionEnd = newSelection;
}
},
setSelectionInBoundaries: function() {
var length = this.text.length;
if (this.selectionStart > length) {
this.selectionStart = length;
} else if (this.selectionStart < 0) {
this.selectionStart = 0;
}
if (this.selectionEnd > length) {
this.selectionEnd = length;
} else if (this.selectionEnd < 0) {
this.selectionEnd = 0;
}
}
});
})();
fabric.util.object.extend(fabric.IText.prototype, {
initDoubleClickSimulation: function() {
this.__lastClickTime = +new Date();
this.__lastLastClickTime = +new Date();
this.__lastPointer = {};
this.on("mousedown", this.onMouseDown.bind(this));
},
onMouseDown: function(options) {
this.__newClickTime = +new Date();
var newPointer = this.canvas.getPointer(options.e);
if (this.isTripleClick(newPointer)) {
this.fire("tripleclick", options);
this._stopEvent(options.e);
} else if (this.isDoubleClick(newPointer)) {
this.fire("dblclick", options);
this._stopEvent(options.e);
}
this.__lastLastClickTime = this.__lastClickTime;
this.__lastClickTime = this.__newClickTime;
this.__lastPointer = newPointer;
this.__lastIsEditing = this.isEditing;
this.__lastSelected = this.selected;
},
isDoubleClick: function(newPointer) {
return this.__newClickTime - this.__lastClickTime < 500 && this.__lastPointer.x === newPointer.x && this.__lastPointer.y === newPointer.y && this.__lastIsEditing;
},
isTripleClick: function(newPointer) {
return this.__newClickTime - this.__lastClickTime < 500 && this.__lastClickTime - this.__lastLastClickTime < 500 && this.__lastPointer.x === newPointer.x && this.__lastPointer.y === newPointer.y;
},
_stopEvent: function(e) {
e.preventDefault && e.preventDefault();
e.stopPropagation && e.stopPropagation();
},
initCursorSelectionHandlers: function() {
this.initSelectedHandler();
this.initMousedownHandler();
this.initMouseupHandler();
this.initClicks();
},
initClicks: function() {
this.on("dblclick", function(options) {
this.selectWord(this.getSelectionStartFromPointer(options.e));
});
this.on("tripleclick", function(options) {
this.selectLine(this.getSelectionStartFromPointer(options.e));
});
},
initMousedownHandler: function() {
this.on("mousedown", function(options) {
if (!this.editable) {
return;
}
var pointer = this.canvas.getPointer(options.e);
this.__mousedownX = pointer.x;
this.__mousedownY = pointer.y;
this.__isMousedown = true;
if (this.selected) {
this.setCursorByClick(options.e);
}
if (this.isEditing) {
this.__selectionStartOnMouseDown = this.selectionStart;
if (this.selectionStart === this.selectionEnd) {
this.abortCursorAnimation();
}
this.renderCursorOrSelection();
}
});
},
_isObjectMoved: function(e) {
var pointer = this.canvas.getPointer(e);
return this.__mousedownX !== pointer.x || this.__mousedownY !== pointer.y;
},
initMouseupHandler: function() {
this.on("mouseup", function(options) {
this.__isMousedown = false;
if (!this.editable || this._isObjectMoved(options.e)) {
return;
}
if (this.__lastSelected && !this.__corner) {
this.enterEditing(options.e);
if (this.selectionStart === this.selectionEnd) {
this.initDelayedCursor(true);
} else {
this.renderCursorOrSelection();
}
}
this.selected = true;
});
},
setCursorByClick: function(e) {
var newSelection = this.getSelectionStartFromPointer(e), start = this.selectionStart, end = this.selectionEnd;
if (e.shiftKey) {
this.setSelectionStartEndWithShift(start, end, newSelection);
} else {
this.selectionStart = newSelection;
this.selectionEnd = newSelection;
}
this._fireSelectionChanged();
this._updateTextarea();
},
getSelectionStartFromPointer: function(e) {
var mouseOffset = this.getLocalPointer(e), prevWidth = 0, width = 0, height = 0, charIndex = 0, newSelectionStart, line;
for (var i = 0, len = this._textLines.length; i < len; i++) {
line = this._textLines[i];
height += this._getHeightOfLine(this.ctx, i) * this.scaleY;
var widthOfLine = this._getLineWidth(this.ctx, i), lineLeftOffset = this._getLineLeftOffset(widthOfLine);
width = lineLeftOffset * this.scaleX;
for (var j = 0, jlen = line.length; j < jlen; j++) {
prevWidth = width;
width += this._getWidthOfChar(this.ctx, line[j], i, this.flipX ? jlen - j : j) * this.scaleX;
if (height <= mouseOffset.y || width <= mouseOffset.x) {
charIndex++;
continue;
}
return this._getNewSelectionStartFromOffset(mouseOffset, prevWidth, width, charIndex + i, jlen);
}
if (mouseOffset.y < height) {
return this._getNewSelectionStartFromOffset(mouseOffset, prevWidth, width, charIndex + i - 1, jlen);
}
}
if (typeof newSelectionStart === "undefined") {
return this.text.length;
}
},
_getNewSelectionStartFromOffset: function(mouseOffset, prevWidth, width, index, jlen) {
var distanceBtwLastCharAndCursor = mouseOffset.x - prevWidth, distanceBtwNextCharAndCursor = width - mouseOffset.x, offset = distanceBtwNextCharAndCursor > distanceBtwLastCharAndCursor ? 0 : 1, newSelectionStart = index + offset;
if (this.flipX) {
newSelectionStart = jlen - newSelectionStart;
}
if (newSelectionStart > this.text.length) {
newSelectionStart = this.text.length;
}
return newSelectionStart;
}
});
fabric.util.object.extend(fabric.IText.prototype, {
initHiddenTextarea: function() {
this.hiddenTextarea = fabric.document.createElement("textarea");
this.hiddenTextarea.setAttribute("autocapitalize", "off");
var style = this._calcTextareaPosition();
this.hiddenTextarea.style.cssText = "position: absolute; top: " + style.top + "; left: " + style.left + ";" + " opacity: 0; width: 0px; height: 0px; z-index: -999;";
fabric.document.body.appendChild(this.hiddenTextarea);
fabric.util.addListener(this.hiddenTextarea, "keydown", this.onKeyDown.bind(this));
fabric.util.addListener(this.hiddenTextarea, "keyup", this.onKeyUp.bind(this));
fabric.util.addListener(this.hiddenTextarea, "input", this.onInput.bind(this));
fabric.util.addListener(this.hiddenTextarea, "copy", this.copy.bind(this));
fabric.util.addListener(this.hiddenTextarea, "cut", this.cut.bind(this));
fabric.util.addListener(this.hiddenTextarea, "paste", this.paste.bind(this));
fabric.util.addListener(this.hiddenTextarea, "compositionstart", this.onCompositionStart.bind(this));
fabric.util.addListener(this.hiddenTextarea, "compositionupdate", this.onCompositionUpdate.bind(this));
fabric.util.addListener(this.hiddenTextarea, "compositionend", this.onCompositionEnd.bind(this));
if (!this._clickHandlerInitialized && this.canvas) {
fabric.util.addListener(this.canvas.upperCanvasEl, "click", this.onClick.bind(this));
this._clickHandlerInitialized = true;
}
},
_keysMap: {
8: "removeChars",
9: "exitEditing",
27: "exitEditing",
13: "insertNewline",
33: "moveCursorUp",
34: "moveCursorDown",
35: "moveCursorRight",
36: "moveCursorLeft",
37: "moveCursorLeft",
38: "moveCursorUp",
39: "moveCursorRight",
40: "moveCursorDown",
46: "forwardDelete"
},
_ctrlKeysMapUp: {
67: "copy",
88: "cut"
},
_ctrlKeysMapDown: {
65: "selectAll"
},
onClick: function() {
this.hiddenTextarea && this.hiddenTextarea.focus();
},
onKeyDown: function(e) {
if (!this.isEditing) {
return;
}
if (e.keyCode in this._keysMap) {
this[this._keysMap[e.keyCode]](e);
} else if (e.keyCode in this._ctrlKeysMapDown && (e.ctrlKey || e.metaKey)) {
this[this._ctrlKeysMapDown[e.keyCode]](e);
} else {
return;
}
e.stopImmediatePropagation();
e.preventDefault();
this.canvas && this.canvas.renderAll();
},
onKeyUp: function(e) {
if (!this.isEditing || this._copyDone) {
this._copyDone = false;
return;
}
if (e.keyCode in this._ctrlKeysMapUp && (e.ctrlKey || e.metaKey)) {
this[this._ctrlKeysMapUp[e.keyCode]](e);
} else {
return;
}
e.stopImmediatePropagation();
e.preventDefault();
this.canvas && this.canvas.renderAll();
},
onInput: function(e) {
if (!this.isEditing || this.inCompositionMode) {
return;
}
var offset = this.selectionStart || 0, offsetEnd = this.selectionEnd || 0, textLength = this.text.length, newTextLength = this.hiddenTextarea.value.length, diff, charsToInsert, start;
if (newTextLength > textLength) {
start = this._selectionDirection === "left" ? offsetEnd : offset;
diff = newTextLength - textLength;
charsToInsert = this.hiddenTextarea.value.slice(start, start + diff);
} else {
diff = newTextLength - textLength + offsetEnd - offset;
charsToInsert = this.hiddenTextarea.value.slice(offset, offset + diff);
}
this.insertChars(charsToInsert);
e.stopPropagation();
},
onCompositionStart: function() {
this.inCompositionMode = true;
this.prevCompositionLength = 0;
this.compositionStart = this.selectionStart;
},
onCompositionEnd: function() {
this.inCompositionMode = false;
},
onCompositionUpdate: function(e) {
var data = e.data;
this.selectionStart = this.compositionStart;
this.selectionEnd = this.selectionEnd === this.selectionStart ? this.compositionStart + this.prevCompositionLength : this.selectionEnd;
this.insertChars(data, false);
this.prevCompositionLength = data.length;
},
forwardDelete: function(e) {
if (this.selectionStart === this.selectionEnd) {
if (this.selectionStart === this.text.length) {
return;
}
this.moveCursorRight(e);
}
this.removeChars(e);
},
copy: function(e) {
if (this.selectionStart === this.selectionEnd) {
return;
}
var selectedText = this.getSelectedText(), clipboardData = this._getClipboardData(e);
if (clipboardData) {
clipboardData.setData("text", selectedText);
}
fabric.copiedText = selectedText;
fabric.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd);
e.stopImmediatePropagation();
e.preventDefault();
this._copyDone = true;
},
paste: function(e) {
var copiedText = null, clipboardData = this._getClipboardData(e), useCopiedStyle = true;
if (clipboardData) {
copiedText = clipboardData.getData("text").replace(/\r/g, "");
if (!fabric.copiedTextStyle || fabric.copiedText !== copiedText) {
useCopiedStyle = false;
}
} else {
copiedText = fabric.copiedText;
}
if (copiedText) {
this.insertChars(copiedText, useCopiedStyle);
}
e.stopImmediatePropagation();
e.preventDefault();
},
cut: function(e) {
if (this.selectionStart === this.selectionEnd) {
return;
}
this.copy(e);
this.removeChars(e);
},
_getClipboardData: function(e) {
return e && e.clipboardData || fabric.window.clipboardData;
},
_getWidthBeforeCursor: function(lineIndex, charIndex) {
var textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex), widthOfLine = this._getLineWidth(this.ctx, lineIndex), widthBeforeCursor = this._getLineLeftOffset(widthOfLine), _char;
for (var i = 0, len = textBeforeCursor.length; i < len; i++) {
_char = textBeforeCursor[i];
widthBeforeCursor += this._getWidthOfChar(this.ctx, _char, lineIndex, i);
}
return widthBeforeCursor;
},
getDownCursorOffset: function(e, isRight) {
var selectionProp = this._getSelectionForOffset(e, isRight), cursorLocation = this.get2DCursorLocation(selectionProp), lineIndex = cursorLocation.lineIndex;
if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) {
return this.text.length - selectionProp;
}
var charIndex = cursorLocation.charIndex, widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex), indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor), textAfterCursor = this._textLines[lineIndex].slice(charIndex);
return textAfterCursor.length + indexOnOtherLine + 2;
},
_getSelectionForOffset: function(e, isRight) {
if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) {
return this.selectionEnd;
} else {
return this.selectionStart;
}
},
getUpCursorOffset: function(e, isRight) {
var selectionProp = this._getSelectionForOffset(e, isRight), cursorLocation = this.get2DCursorLocation(selectionProp), lineIndex = cursorLocation.lineIndex;
if (lineIndex === 0 || e.metaKey || e.keyCode === 33) {
return -selectionProp;
}
var charIndex = cursorLocation.charIndex, widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex), indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor), textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex);
return -this._textLines[lineIndex - 1].length + indexOnOtherLine - textBeforeCursor.length;
},
_getIndexOnLine: function(lineIndex, width) {
var widthOfLine = this._getLineWidth(this.ctx, lineIndex), textOnLine = this._textLines[lineIndex], lineLeftOffset = this._getLineLeftOffset(widthOfLine), widthOfCharsOnLine = lineLeftOffset, indexOnLine = 0, foundMatch;
for (var j = 0, jlen = textOnLine.length; j < jlen; j++) {
var _char = textOnLine[j], widthOfChar = this._getWidthOfChar(this.ctx, _char, lineIndex, j);
widthOfCharsOnLine += widthOfChar;
if (widthOfCharsOnLine > width) {
foundMatch = true;
var leftEdge = widthOfCharsOnLine - widthOfChar, rightEdge = widthOfCharsOnLine, offsetFromLeftEdge = Math.abs(leftEdge - width), offsetFromRightEdge = Math.abs(rightEdge - width);
indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : j - 1;
break;
}
}
if (!foundMatch) {
indexOnLine = textOnLine.length - 1;
}
return indexOnLine;
},
moveCursorDown: function(e) {
if (this.selectionStart >= this.text.length && this.selectionEnd >= this.text.length) {
return;
}
this._moveCursorUpOrDown("Down", e);
},
moveCursorUp: function(e) {
if (this.selectionStart === 0 && this.selectionEnd === 0) {
return;
}
this._moveCursorUpOrDown("Up", e);
},
_moveCursorUpOrDown: function(direction, e) {
var action = "get" + direction + "CursorOffset", offset = this[action](e, this._selectionDirection === "right");
if (e.shiftKey) {
this.moveCursorWithShift(offset);
} else {
this.moveCursorWithoutShift(offset);
}
if (offset !== 0) {
this.setSelectionInBoundaries();
this.abortCursorAnimation();
this._currentCursorOpacity = 1;
this.initDelayedCursor();
this._fireSelectionChanged();
this._updateTextarea();
}
},
moveCursorWithShift: function(offset) {
var newSelection = this._selectionDirection === "left" ? this.selectionStart + offset : this.selectionEnd + offset;
this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, newSelection);
return offset !== 0;
},
moveCursorWithoutShift: function(offset) {
if (offset < 0) {
this.selectionStart += offset;
this.selectionEnd = this.selectionStart;
} else {
this.selectionEnd += offset;
this.selectionStart = this.selectionEnd;
}
return offset !== 0;
},
moveCursorLeft: function(e) {
if (this.selectionStart === 0 && this.selectionEnd === 0) {
return;
}
this._moveCursorLeftOrRight("Left", e);
},
_move: function(e, prop, direction) {
var newValue;
if (e.altKey) {
newValue = this["findWordBoundary" + direction](this[prop]);
} else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36) {
newValue = this["findLineBoundary" + direction](this[prop]);
} else {
this[prop] += direction === "Left" ? -1 : 1;
return true;
}
if (typeof newValue !== undefined && this[prop] !== newValue) {
this[prop] = newValue;
return true;
}
},
_moveLeft: function(e, prop) {
return this._move(e, prop, "Left");
},
_moveRight: function(e, prop) {
return this._move(e, prop, "Right");
},
moveCursorLeftWithoutShift: function(e) {
var change = true;
this._selectionDirection = "left";
if (this.selectionEnd === this.selectionStart && this.selectionStart !== 0) {
change = this._moveLeft(e, "selectionStart");
}
this.selectionEnd = this.selectionStart;
return change;
},
moveCursorLeftWithShift: function(e) {
if (this._selectionDirection === "right" && this.selectionStart !== this.selectionEnd) {
return this._moveLeft(e, "selectionEnd");
} else if (this.selectionStart !== 0) {
this._selectionDirection = "left";
return this._moveLeft(e, "selectionStart");
}
},
moveCursorRight: function(e) {
if (this.selectionStart >= this.text.length && this.selectionEnd >= this.text.length) {
return;
}
this._moveCursorLeftOrRight("Right", e);
},
_moveCursorLeftOrRight: function(direction, e) {
var actionName = "moveCursor" + direction + "With";
this._currentCursorOpacity = 1;
if (e.shiftKey) {
actionName += "Shift";
} else {
actionName += "outShift";
}
if (this[actionName](e)) {
this.abortCursorAnimation();
this.initDelayedCursor();
this._fireSelectionChanged();
this._updateTextarea();
}
},
moveCursorRightWithShift: function(e) {
if (this._selectionDirection === "left" && this.selectionStart !== this.selectionEnd) {
return this._moveRight(e, "selectionStart");
} else if (this.selectionEnd !== this.text.length) {
this._selectionDirection = "right";
return this._moveRight(e, "selectionEnd");
}
},
moveCursorRightWithoutShift: function(e) {
var changed = true;
this._selectionDirection = "right";
if (this.selectionStart === this.selectionEnd) {
changed = this._moveRight(e, "selectionStart");
this.selectionEnd = this.selectionStart;
} else {
this.selectionStart = this.selectionEnd;
}
return changed;
},
removeChars: function(e) {
if (this.selectionStart === this.selectionEnd) {
this._removeCharsNearCursor(e);
} else {
this._removeCharsFromTo(this.selectionStart, this.selectionEnd);
}
this.setSelectionEnd(this.selectionStart);
this._removeExtraneousStyles();
this.canvas && this.canvas.renderAll();
this.setCoords();
this.fire("changed");
this.canvas && this.canvas.fire("text:changed", {
target: this
});
},
_removeCharsNearCursor: function(e) {
if (this.selectionStart === 0) {
return;
}
if (e.metaKey) {
var leftLineBoundary = this.findLineBoundaryLeft(this.selectionStart);
this._removeCharsFromTo(leftLineBoundary, this.selectionStart);
this.setSelectionStart(leftLineBoundary);
} else if (e.altKey) {
var leftWordBoundary = this.findWordBoundaryLeft(this.selectionStart);
this._removeCharsFromTo(leftWordBoundary, this.selectionStart);
this.setSelectionStart(leftWordBoundary);
} else {
this._removeSingleCharAndStyle(this.selectionStart);
this.setSelectionStart(this.selectionStart - 1);
}
}
});
(function() {
var toFixed = fabric.util.toFixed, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;
fabric.util.object.extend(fabric.IText.prototype, {
_setSVGTextLineText: function(lineIndex, textSpans, height, textLeftOffset, textTopOffset, textBgRects) {
if (!this._getLineStyle(lineIndex)) {
fabric.Text.prototype._setSVGTextLineText.call(this, lineIndex, textSpans, height, textLeftOffset, textTopOffset);
} else {
this._setSVGTextLineChars(lineIndex, textSpans, height, textLeftOffset, textBgRects);
}
},
_setSVGTextLineChars: function(lineIndex, textSpans, height, textLeftOffset, textBgRects) {
var chars = this._textLines[lineIndex], charOffset = 0, lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(this.ctx, lineIndex)) - this.width / 2, lineOffset = this._getSVGLineTopOffset(lineIndex), heightOfLine = this._getHeightOfLine(this.ctx, lineIndex);
for (var i = 0, len = chars.length; i < len; i++) {
var styleDecl = this._getStyleDeclaration(lineIndex, i) || {};
textSpans.push(this._createTextCharSpan(chars[i], styleDecl, lineLeftOffset, lineOffset.lineTop + lineOffset.offset, charOffset));
var charWidth = this._getWidthOfChar(this.ctx, chars[i], lineIndex, i);
if (styleDecl.textBackgroundColor) {
textBgRects.push(this._createTextCharBg(styleDecl, lineLeftOffset, lineOffset.lineTop, heightOfLine, charWidth, charOffset));
}
charOffset += charWidth;
}
},
_getSVGLineTopOffset: function(lineIndex) {
var lineTopOffset = 0, lastHeight = 0;
for (var j = 0; j < lineIndex; j++) {
lineTopOffset += this._getHeightOfLine(this.ctx, j);
}
lastHeight = this._getHeightOfLine(this.ctx, j);
return {
lineTop: lineTopOffset,
offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult)
};
},
_createTextCharBg: function(styleDecl, lineLeftOffset, lineTopOffset, heightOfLine, charWidth, charOffset) {
return [ '\t\t<rect fill="', styleDecl.textBackgroundColor, '" x="', toFixed(lineLeftOffset + charOffset, NUM_FRACTION_DIGITS), '" y="', toFixed(lineTopOffset - this.height / 2, NUM_FRACTION_DIGITS), '" width="', toFixed(charWidth, NUM_FRACTION_DIGITS), '" height="', toFixed(heightOfLine / this.lineHeight, NUM_FRACTION_DIGITS), '"></rect>\n' ].join("");
},
_createTextCharSpan: function(_char, styleDecl, lineLeftOffset, lineTopOffset, charOffset) {
var fillStyles = this.getSvgStyles.call(fabric.util.object.extend({
visible: true,
fill: this.fill,
stroke: this.stroke,
type: "text",
getSvgFilter: fabric.Object.prototype.getSvgFilter
}, styleDecl));
return [ '\t\t\t<tspan x="', toFixed(lineLeftOffset + charOffset, NUM_FRACTION_DIGITS), '" y="', toFixed(lineTopOffset - this.height / 2, NUM_FRACTION_DIGITS), '" ', styleDecl.fontFamily ? 'font-family="' + styleDecl.fontFamily.replace(/"/g, "'") + '" ' : "", styleDecl.fontSize ? 'font-size="' + styleDecl.fontSize + '" ' : "", styleDecl.fontStyle ? 'font-style="' + styleDecl.fontStyle + '" ' : "", styleDecl.fontWeight ? 'font-weight="' + styleDecl.fontWeight + '" ' : "", styleDecl.textDecoration ? 'text-decoration="' + styleDecl.textDecoration + '" ' : "", 'style="', fillStyles, '">', fabric.util.string.escapeXml(_char), "</tspan>\n" ].join("");
}
});
})();
(function(global) {
"use strict";
var fabric = global.fabric || (global.fabric = {}), clone = fabric.util.object.clone;
fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, {
type: "textbox",
minWidth: 20,
dynamicMinWidth: 2,
__cachedLines: null,
lockScalingY: true,
lockScalingFlip: true,
initialize: function(text, options) {
this.ctx = fabric.util.createCanvasElement().getContext("2d");
this.callSuper("initialize", text, options);
this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility());
this._dimensionAffectingProps.width = true;
},
_initDimensions: function(ctx) {
if (this.__skipDimension) {
return;
}
if (!ctx) {
ctx = fabric.util.createCanvasElement().getContext("2d");
this._setTextStyles(ctx);
}
this.dynamicMinWidth = 0;
this._textLines = this._splitTextIntoLines();
if (this.dynamicMinWidth > this.width) {
this._set("width", this.dynamicMinWidth);
}
this._clearCache();
this.height = this._getTextHeight(ctx);
},
_generateStyleMap: function() {
var realLineCount = 0, realLineCharCount = 0, charCount = 0, map = {};
for (var i = 0; i < this._textLines.length; i++) {
if (this.text[charCount] === "\n" && i > 0) {
realLineCharCount = 0;
charCount++;
realLineCount++;
} else if (this.text[charCount] === " " && i > 0) {
realLineCharCount++;
charCount++;
}
map[i] = {
line: realLineCount,
offset: realLineCharCount
};
charCount += this._textLines[i].length;
realLineCharCount += this._textLines[i].length;
}
return map;
},
_getStyleDeclaration: function(lineIndex, charIndex, returnCloneOrEmpty) {
if (this._styleMap) {
var map = this._styleMap[lineIndex];
if (!map) {
return returnCloneOrEmpty ? {} : null;
}
lineIndex = map.line;
charIndex = map.offset + charIndex;
}
return this.callSuper("_getStyleDeclaration", lineIndex, charIndex, returnCloneOrEmpty);
},
_setStyleDeclaration: function(lineIndex, charIndex, style) {
var map = this._styleMap[lineIndex];
lineIndex = map.line;
charIndex = map.offset + charIndex;
this.styles[lineIndex][charIndex] = style;
},
_deleteStyleDeclaration: function(lineIndex, charIndex) {
var map = this._styleMap[lineIndex];
lineIndex = map.line;
charIndex = map.offset + charIndex;
delete this.styles[lineIndex][charIndex];
},
_getLineStyle: function(lineIndex) {
var map = this._styleMap[lineIndex];
return this.styles[map.line];
},
_setLineStyle: function(lineIndex, style) {
var map = this._styleMap[lineIndex];
this.styles[map.line] = style;
},
_deleteLineStyle: function(lineIndex) {
var map = this._styleMap[lineIndex];
delete this.styles[map.line];
},
_wrapText: function(ctx, text) {
var lines = text.split(this._reNewline), wrapped = [], i;
for (i = 0; i < lines.length; i++) {
wrapped = wrapped.concat(this._wrapLine(ctx, lines[i], i));
}
return wrapped;
},
_measureText: function(ctx, text, lineIndex, charOffset) {
var width = 0;
charOffset = charOffset || 0;
for (var i = 0, len = text.length; i < len; i++) {
width += this._getWidthOfChar(ctx, text[i], lineIndex, i + charOffset);
}
return width;
},
_wrapLine: function(ctx, text, lineIndex) {
var lineWidth = 0, lines = [], line = "", words = text.split(" "), word = "", offset = 0, infix = " ", wordWidth = 0, infixWidth = 0, largestWordWidth = 0, lineJustStarted = true, additionalSpace = this._getWidthOfCharSpacing();
for (var i = 0; i < words.length; i++) {
word = words[i];
wordWidth = this._measureText(ctx, word, lineIndex, offset);
offset += word.length;
lineWidth += infixWidth + wordWidth - additionalSpace;
if (lineWidth >= this.width && !lineJustStarted) {
lines.push(line);
line = "";
lineWidth = wordWidth;
lineJustStarted = true;
} else {
lineWidth += additionalSpace;
}
if (!lineJustStarted) {
line += infix;
}
line += word;
infixWidth = this._measureText(ctx, infix, lineIndex, offset);
offset++;
lineJustStarted = false;
if (wordWidth > largestWordWidth) {
largestWordWidth = wordWidth;
}
}
i && lines.push(line);
if (largestWordWidth > this.dynamicMinWidth) {
this.dynamicMinWidth = largestWordWidth - additionalSpace;
}
return lines;
},
_splitTextIntoLines: function() {
var originalAlign = this.textAlign;
this.ctx.save();
this._setTextStyles(this.ctx);
this.textAlign = "left";
var lines = this._wrapText(this.ctx, this.text);
this.textAlign = originalAlign;
this.ctx.restore();
this._textLines = lines;
this._styleMap = this._generateStyleMap();
return lines;
},
setOnGroup: function(key, value) {
if (key === "scaleX") {
this.set("scaleX", Math.abs(1 / value));
this.set("width", this.get("width") * value / (typeof this.__oldScaleX === "undefined" ? 1 : this.__oldScaleX));
this.__oldScaleX = value;
}
},
get2DCursorLocation: function(selectionStart) {
if (typeof selectionStart === "undefined") {
selectionStart = this.selectionStart;
}
var numLines = this._textLines.length, removed = 0;
for (var i = 0; i < numLines; i++) {
var line = this._textLines[i], lineLen = line.length;
if (selectionStart <= removed + lineLen) {
return {
lineIndex: i,
charIndex: selectionStart - removed
};
}
removed += lineLen;
if (this.text[removed] === "\n" || this.text[removed] === " ") {
removed++;
}
}
return {
lineIndex: numLines - 1,
charIndex: this._textLines[numLines - 1].length
};
},
_getCursorBoundariesOffsets: function(chars, typeOfBoundaries) {
var topOffset = 0, leftOffset = 0, cursorLocation = this.get2DCursorLocation(), lineChars = this._textLines[cursorLocation.lineIndex].split(""), lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(this.ctx, cursorLocation.lineIndex));
for (var i = 0; i < cursorLocation.charIndex; i++) {
leftOffset += this._getWidthOfChar(this.ctx, lineChars[i], cursorLocation.lineIndex, i);
}
for (i = 0; i < cursorLocation.lineIndex; i++) {
topOffset += this._getHeightOfLine(this.ctx, i);
}
if (typeOfBoundaries === "cursor") {
topOffset += (1 - this._fontSizeFraction) * this._getHeightOfLine(this.ctx, cursorLocation.lineIndex) / this.lineHeight - this.getCurrentCharFontSize(cursorLocation.lineIndex, cursorLocation.charIndex) * (1 - this._fontSizeFraction);
}
return {
top: topOffset,
left: leftOffset,
lineLeft: lineLeftOffset
};
},
getMinWidth: function() {
return Math.max(this.minWidth, this.dynamicMinWidth);
},
toObject: function(propertiesToInclude) {
return this.callSuper("toObject", [ "minWidth" ].concat(propertiesToInclude));
}
});
fabric.Textbox.fromObject = function(object, callback) {
var textbox = new fabric.Textbox(object.text, clone(object));
callback && callback(textbox);
return textbox;
};
fabric.Textbox.getTextboxControlVisibility = function() {
return {
tl: false,
tr: false,
br: false,
bl: false,
ml: true,
mt: false,
mr: true,
mb: false,
mtr: true
};
};
})( true ? exports : this);
(function() {
var setObjectScaleOverridden = fabric.Canvas.prototype._setObjectScale;
fabric.Canvas.prototype._setObjectScale = function(localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip, _dim) {
var t = transform.target;
if (t instanceof fabric.Textbox) {
var w = t.width * (localMouse.x / transform.scaleX / (t.width + t.strokeWidth));
if (w >= t.getMinWidth()) {
t.set("width", w);
return true;
}
} else {
return setObjectScaleOverridden.call(fabric.Canvas.prototype, localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip, _dim);
}
};
fabric.Group.prototype._refreshControlsVisibility = function() {
if (typeof fabric.Textbox === "undefined") {
return;
}
for (var i = this._objects.length; i--; ) {
if (this._objects[i] instanceof fabric.Textbox) {
this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility());
return;
}
}
};
var clone = fabric.util.object.clone;
fabric.util.object.extend(fabric.Textbox.prototype, {
_removeExtraneousStyles: function() {
for (var prop in this._styleMap) {
if (!this._textLines[prop]) {
delete this.styles[this._styleMap[prop].line];
}
}
},
insertCharStyleObject: function(lineIndex, charIndex, style) {
var map = this._styleMap[lineIndex];
lineIndex = map.line;
charIndex = map.offset + charIndex;
fabric.IText.prototype.insertCharStyleObject.apply(this, [ lineIndex, charIndex, style ]);
},
insertNewlineStyleObject: function(lineIndex, charIndex, isEndOfLine) {
var map = this._styleMap[lineIndex];
lineIndex = map.line;
charIndex = map.offset + charIndex;
fabric.IText.prototype.insertNewlineStyleObject.apply(this, [ lineIndex, charIndex, isEndOfLine ]);
},
shiftLineStyles: function(lineIndex, offset) {
var clonedStyles = clone(this.styles), map = this._styleMap[lineIndex];
lineIndex = map.line;
for (var line in this.styles) {
var numericLine = parseInt(line, 10);
if (numericLine > lineIndex) {
this.styles[numericLine + offset] = clonedStyles[numericLine];
if (!clonedStyles[numericLine - offset]) {
delete this.styles[numericLine];
}
}
}
},
_getTextOnPreviousLine: function(lIndex) {
var textOnPreviousLine = this._textLines[lIndex - 1];
while (this._styleMap[lIndex - 2] && this._styleMap[lIndex - 2].line === this._styleMap[lIndex - 1].line) {
textOnPreviousLine = this._textLines[lIndex - 2] + textOnPreviousLine;
lIndex--;
}
return textOnPreviousLine;
},
removeStyleObject: function(isBeginningOfLine, index) {
var cursorLocation = this.get2DCursorLocation(index), map = this._styleMap[cursorLocation.lineIndex], lineIndex = map.line, charIndex = map.offset + cursorLocation.charIndex;
this._removeStyleObject(isBeginningOfLine, cursorLocation, lineIndex, charIndex);
}
});
})();
(function() {
var override = fabric.IText.prototype._getNewSelectionStartFromOffset;
fabric.IText.prototype._getNewSelectionStartFromOffset = function(mouseOffset, prevWidth, width, index, jlen) {
index = override.call(this, mouseOffset, prevWidth, width, index, jlen);
var tmp = 0, removed = 0;
for (var i = 0; i < this._textLines.length; i++) {
tmp += this._textLines[i].length;
if (tmp + removed >= index) {
break;
}
if (this.text[tmp + removed] === "\n" || this.text[tmp + removed] === " ") {
removed++;
}
}
return index - i + removed;
};
})();
(function() {
if (typeof document !== "undefined" && typeof window !== "undefined") {
return;
}
var DOMParser = __webpack_require__(113).DOMParser, URL = __webpack_require__(114), HTTP = __webpack_require__(121), HTTPS = __webpack_require__(148), Canvas = __webpack_require__(112), Image = __webpack_require__(112).Image;
function request(url, encoding, callback) {
var oURL = URL.parse(url);
if (!oURL.port) {
oURL.port = oURL.protocol.indexOf("https:") === 0 ? 443 : 80;
}
var reqHandler = oURL.protocol.indexOf("https:") === 0 ? HTTPS : HTTP, req = reqHandler.request({
hostname: oURL.hostname,
port: oURL.port,
path: oURL.path,
method: "GET"
}, function(response) {
var body = "";
if (encoding) {
response.setEncoding(encoding);
}
response.on("end", function() {
callback(body);
});
response.on("data", function(chunk) {
if (response.statusCode === 200) {
body += chunk;
}
});
});
req.on("error", function(err) {
if (err.errno === process.ECONNREFUSED) {
fabric.log("ECONNREFUSED: connection refused to " + oURL.hostname + ":" + oURL.port);
} else {
fabric.log(err.message);
}
callback(null);
});
req.end();
}
function requestFs(path, callback) {
var fs = __webpack_require__(149);
fs.readFile(path, function(err, data) {
if (err) {
fabric.log(err);
throw err;
} else {
callback(data);
}
});
}
fabric.util.loadImage = function(url, callback, context) {
function createImageAndCallBack(data) {
if (data) {
img.src = new Buffer(data, "binary");
img._src = url;
callback && callback.call(context, img);
} else {
img = null;
callback && callback.call(context, null, true);
}
}
var img = new Image();
if (url && (url instanceof Buffer || url.indexOf("data") === 0)) {
img.src = img._src = url;
callback && callback.call(context, img);
} else if (url && url.indexOf("http") !== 0) {
requestFs(url, createImageAndCallBack);
} else if (url) {
request(url, "binary", createImageAndCallBack);
} else {
callback && callback.call(context, url);
}
};
fabric.loadSVGFromURL = function(url, callback, reviver) {
url = url.replace(/^\n\s*/, "").replace(/\?.*$/, "").trim();
if (url.indexOf("http") !== 0) {
requestFs(url, function(body) {
fabric.loadSVGFromString(body.toString(), callback, reviver);
});
} else {
request(url, "", function(body) {
fabric.loadSVGFromString(body, callback, reviver);
});
}
};
fabric.loadSVGFromString = function(string, callback, reviver) {
var doc = new DOMParser().parseFromString(string);
fabric.parseSVGDocument(doc.documentElement, function(results, options) {
callback && callback(results, options);
}, reviver);
};
fabric.util.getScript = function(url, callback) {
request(url, "", function(body) {
eval(body);
callback && callback();
});
};
fabric.createCanvasForNode = function(width, height, options, nodeCanvasOptions) {
nodeCanvasOptions = nodeCanvasOptions || options;
var canvasEl = fabric.document.createElement("canvas"), nodeCanvas = new Canvas(width || 600, height || 600, nodeCanvasOptions), nodeCacheCanvas = new Canvas(width || 600, height || 600, nodeCanvasOptions);
canvasEl.style = {};
canvasEl.width = nodeCanvas.width;
canvasEl.height = nodeCanvas.height;
options = options || {};
options.nodeCanvas = nodeCanvas;
options.nodeCacheCanvas = nodeCacheCanvas;
var FabricCanvas = fabric.Canvas || fabric.StaticCanvas, fabricCanvas = new FabricCanvas(canvasEl, options);
fabricCanvas.nodeCanvas = nodeCanvas;
fabricCanvas.nodeCacheCanvas = nodeCacheCanvas;
fabricCanvas.contextContainer = nodeCanvas.getContext("2d");
fabricCanvas.contextCache = nodeCacheCanvas.getContext("2d");
fabricCanvas.Font = Canvas.Font;
return fabricCanvas;
};
var originaInitStatic = fabric.StaticCanvas.prototype._initStatic;
fabric.StaticCanvas.prototype._initStatic = function(el, options) {
el = el || fabric.document.createElement("canvas");
this.nodeCanvas = new Canvas(el.width, el.height);
this.nodeCacheCanvas = new Canvas(el.width, el.height);
originaInitStatic.call(this, el, options);
this.contextContainer = this.nodeCanvas.getContext("2d");
this.contextCache = this.nodeCacheCanvas.getContext("2d");
this.Font = Canvas.Font;
};
fabric.StaticCanvas.prototype.createPNGStream = function() {
return this.nodeCanvas.createPNGStream();
};
fabric.StaticCanvas.prototype.createJPEGStream = function(opts) {
return this.nodeCanvas.createJPEGStream(opts);
};
fabric.StaticCanvas.prototype._initRetinaScaling = function() {
if (!this._isRetinaScaling()) {
return;
}
this.lowerCanvasEl.setAttribute("width", this.width * fabric.devicePixelRatio);
this.lowerCanvasEl.setAttribute("height", this.height * fabric.devicePixelRatio);
this.nodeCanvas.width = this.width * fabric.devicePixelRatio;
this.nodeCanvas.height = this.height * fabric.devicePixelRatio;
this.contextContainer.scale(fabric.devicePixelRatio, fabric.devicePixelRatio);
return this;
};
if (fabric.Canvas) {
fabric.Canvas.prototype._initRetinaScaling = fabric.StaticCanvas.prototype._initRetinaScaling;
}
var origSetBackstoreDimension = fabric.StaticCanvas.prototype._setBackstoreDimension;
fabric.StaticCanvas.prototype._setBackstoreDimension = function(prop, value) {
origSetBackstoreDimension.call(this, prop, value);
this.nodeCanvas[prop] = value;
return this;
};
if (fabric.Canvas) {
fabric.Canvas.prototype._setBackstoreDimension = fabric.StaticCanvas.prototype._setBackstoreDimension;
}
})();
window.fabric = fabric;
if (true) {
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
return fabric;
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
}
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(106).Buffer, (function() { return this; }()), __webpack_require__(110)))
/***/ }),
/* 106 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* @license MIT
*/
/* eslint-disable no-proto */
'use strict'
var base64 = __webpack_require__(107)
var ieee754 = __webpack_require__(108)
var isArray = __webpack_require__(109)
exports.Buffer = Buffer
exports.SlowBuffer = SlowBuffer
exports.INSPECT_MAX_BYTES = 50
/**
* If `Buffer.TYPED_ARRAY_SUPPORT`:
* === true Use Uint8Array implementation (fastest)
* === false Use Object implementation (most compatible, even IE6)
*
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
* Opera 11.6+, iOS 4.2+.
*
* Due to various browser bugs, sometimes the Object implementation will be used even
* when the browser supports typed arrays.
*
* Note:
*
* - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
* See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
*
* - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
*
* - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
* incorrect length in some situations.
* We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
* get the Object implementation, which is slower but behaves correctly.
*/
Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
? global.TYPED_ARRAY_SUPPORT
: typedArraySupport()
/*
* Export kMaxLength after typed array support is determined.
*/
exports.kMaxLength = kMaxLength()
function typedArraySupport () {
try {
var arr = new Uint8Array(1)
arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}
return arr.foo() === 42 && // typed array instances can be augmented
typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
} catch (e) {
return false
}
}
function kMaxLength () {
return Buffer.TYPED_ARRAY_SUPPORT
? 0x7fffffff
: 0x3fffffff
}
function createBuffer (that, length) {
if (kMaxLength() < length) {
throw new RangeError('Invalid typed array length')
}
if (Buffer.TYPED_ARRAY_SUPPORT) {
// Return an augmented `Uint8Array` instance, for best performance
that = new Uint8Array(length)
that.__proto__ = Buffer.prototype
} else {
// Fallback: Return an object instance of the Buffer class
if (that === null) {
that = new Buffer(length)
}
that.length = length
}
return that
}
/**
* The Buffer constructor returns instances of `Uint8Array` that have their
* prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
* `Uint8Array`, so the returned instances will have all the node `Buffer` methods
* and the `Uint8Array` methods. Square bracket notation works as expected -- it
* returns a single octet.
*
* The `Uint8Array` prototype remains unmodified.
*/
function Buffer (arg, encodingOrOffset, length) {
if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {
return new Buffer(arg, encodingOrOffset, length)
}
// Common case.
if (typeof arg === 'number') {
if (typeof encodingOrOffset === 'string') {
throw new Error(
'If encoding is specified then the first argument must be a string'
)
}
return allocUnsafe(this, arg)
}
return from(this, arg, encodingOrOffset, length)
}
Buffer.poolSize = 8192 // not used by this implementation
// TODO: Legacy, not needed anymore. Remove in next major version.
Buffer._augment = function (arr) {
arr.__proto__ = Buffer.prototype
return arr
}
function from (that, value, encodingOrOffset, length) {
if (typeof value === 'number') {
throw new TypeError('"value" argument must not be a number')
}
if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
return fromArrayBuffer(that, value, encodingOrOffset, length)
}
if (typeof value === 'string') {
return fromString(that, value, encodingOrOffset)
}
return fromObject(that, value)
}
/**
* Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
* if value is a number.
* Buffer.from(str[, encoding])
* Buffer.from(array)
* Buffer.from(buffer)
* Buffer.from(arrayBuffer[, byteOffset[, length]])
**/
Buffer.from = function (value, encodingOrOffset, length) {
return from(null, value, encodingOrOffset, length)
}
if (Buffer.TYPED_ARRAY_SUPPORT) {
Buffer.prototype.__proto__ = Uint8Array.prototype
Buffer.__proto__ = Uint8Array
if (typeof Symbol !== 'undefined' && Symbol.species &&
Buffer[Symbol.species] === Buffer) {
// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
Object.defineProperty(Buffer, Symbol.species, {
value: null,
configurable: true
})
}
}
function assertSize (size) {
if (typeof size !== 'number') {
throw new TypeError('"size" argument must be a number')
} else if (size < 0) {
throw new RangeError('"size" argument must not be negative')
}
}
function alloc (that, size, fill, encoding) {
assertSize(size)
if (size <= 0) {
return createBuffer(that, size)
}
if (fill !== undefined) {
// Only pay attention to encoding if it's a string. This
// prevents accidentally sending in a number that would
// be interpretted as a start offset.
return typeof encoding === 'string'
? createBuffer(that, size).fill(fill, encoding)
: createBuffer(that, size).fill(fill)
}
return createBuffer(that, size)
}
/**
* Creates a new filled Buffer instance.
* alloc(size[, fill[, encoding]])
**/
Buffer.alloc = function (size, fill, encoding) {
return alloc(null, size, fill, encoding)
}
function allocUnsafe (that, size) {
assertSize(size)
that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)
if (!Buffer.TYPED_ARRAY_SUPPORT) {
for (var i = 0; i < size; ++i) {
that[i] = 0
}
}
return that
}
/**
* Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
* */
Buffer.allocUnsafe = function (size) {
return allocUnsafe(null, size)
}
/**
* Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
*/
Buffer.allocUnsafeSlow = function (size) {
return allocUnsafe(null, size)
}
function fromString (that, string, encoding) {
if (typeof encoding !== 'string' || encoding === '') {
encoding = 'utf8'
}
if (!Buffer.isEncoding(encoding)) {
throw new TypeError('"encoding" must be a valid string encoding')
}
var length = byteLength(string, encoding) | 0
that = createBuffer(that, length)
var actual = that.write(string, encoding)
if (actual !== length) {
// Writing a hex string, for example, that contains invalid characters will
// cause everything after the first invalid character to be ignored. (e.g.
// 'abxxcd' will be treated as 'ab')
that = that.slice(0, actual)
}
return that
}
function fromArrayLike (that, array) {
var length = array.length < 0 ? 0 : checked(array.length) | 0
that = createBuffer(that, length)
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
function fromArrayBuffer (that, array, byteOffset, length) {
array.byteLength // this throws if `array` is not a valid ArrayBuffer
if (byteOffset < 0 || array.byteLength < byteOffset) {
throw new RangeError('\'offset\' is out of bounds')
}
if (array.byteLength < byteOffset + (length || 0)) {
throw new RangeError('\'length\' is out of bounds')
}
if (byteOffset === undefined && length === undefined) {
array = new Uint8Array(array)
} else if (length === undefined) {
array = new Uint8Array(array, byteOffset)
} else {
array = new Uint8Array(array, byteOffset, length)
}
if (Buffer.TYPED_ARRAY_SUPPORT) {
// Return an augmented `Uint8Array` instance, for best performance
that = array
that.__proto__ = Buffer.prototype
} else {
// Fallback: Return an object instance of the Buffer class
that = fromArrayLike(that, array)
}
return that
}
function fromObject (that, obj) {
if (Buffer.isBuffer(obj)) {
var len = checked(obj.length) | 0
that = createBuffer(that, len)
if (that.length === 0) {
return that
}
obj.copy(that, 0, 0, len)
return that
}
if (obj) {
if ((typeof ArrayBuffer !== 'undefined' &&
obj.buffer instanceof ArrayBuffer) || 'length' in obj) {
if (typeof obj.length !== 'number' || isnan(obj.length)) {
return createBuffer(that, 0)
}
return fromArrayLike(that, obj)
}
if (obj.type === 'Buffer' && isArray(obj.data)) {
return fromArrayLike(that, obj.data)
}
}
throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')
}
function checked (length) {
// Note: cannot use `length < kMaxLength()` here because that fails when
// length is NaN (which is otherwise coerced to zero.)
if (length >= kMaxLength()) {
throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
'size: 0x' + kMaxLength().toString(16) + ' bytes')
}
return length | 0
}
function SlowBuffer (length) {
if (+length != length) { // eslint-disable-line eqeqeq
length = 0
}
return Buffer.alloc(+length)
}
Buffer.isBuffer = function isBuffer (b) {
return !!(b != null && b._isBuffer)
}
Buffer.compare = function compare (a, b) {
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
throw new TypeError('Arguments must be Buffers')
}
if (a === b) return 0
var x = a.length
var y = b.length
for (var i = 0, len = Math.min(x, y); i < len; ++i) {
if (a[i] !== b[i]) {
x = a[i]
y = b[i]
break
}
}
if (x < y) return -1
if (y < x) return 1
return 0
}
Buffer.isEncoding = function isEncoding (encoding) {
switch (String(encoding).toLowerCase()) {
case 'hex':
case 'utf8':
case 'utf-8':
case 'ascii':
case 'latin1':
case 'binary':
case 'base64':
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return true
default:
return false
}
}
Buffer.concat = function concat (list, length) {
if (!isArray(list)) {
throw new TypeError('"list" argument must be an Array of Buffers')
}
if (list.length === 0) {
return Buffer.alloc(0)
}
var i
if (length === undefined) {
length = 0
for (i = 0; i < list.length; ++i) {
length += list[i].length
}
}
var buffer = Buffer.allocUnsafe(length)
var pos = 0
for (i = 0; i < list.length; ++i) {
var buf = list[i]
if (!Buffer.isBuffer(buf)) {
throw new TypeError('"list" argument must be an Array of Buffers')
}
buf.copy(buffer, pos)
pos += buf.length
}
return buffer
}
function byteLength (string, encoding) {
if (Buffer.isBuffer(string)) {
return string.length
}
if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&
(ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {
return string.byteLength
}
if (typeof string !== 'string') {
string = '' + string
}
var len = string.length
if (len === 0) return 0
// Use a for loop to avoid recursion
var loweredCase = false
for (;;) {
switch (encoding) {
case 'ascii':
case 'latin1':
case 'binary':
return len
case 'utf8':
case 'utf-8':
case undefined:
return utf8ToBytes(string).length
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return len * 2
case 'hex':
return len >>> 1
case 'base64':
return base64ToBytes(string).length
default:
if (loweredCase) return utf8ToBytes(string).length // assume utf8
encoding = ('' + encoding).toLowerCase()
loweredCase = true
}
}
}
Buffer.byteLength = byteLength
function slowToString (encoding, start, end) {
var loweredCase = false
// No need to verify that "this.length <= MAX_UINT32" since it's a read-only
// property of a typed array.
// This behaves neither like String nor Uint8Array in that we set start/end
// to their upper/lower bounds if the value passed is out of range.
// undefined is handled specially as per ECMA-262 6th Edition,
// Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
if (start === undefined || start < 0) {
start = 0
}
// Return early if start > this.length. Done here to prevent potential uint32
// coercion fail below.
if (start > this.length) {
return ''
}
if (end === undefined || end > this.length) {
end = this.length
}
if (end <= 0) {
return ''
}
// Force coersion to uint32. This will also coerce falsey/NaN values to 0.
end >>>= 0
start >>>= 0
if (end <= start) {
return ''
}
if (!encoding) encoding = 'utf8'
while (true) {
switch (encoding) {
case 'hex':
return hexSlice(this, start, end)
case 'utf8':
case 'utf-8':
return utf8Slice(this, start, end)
case 'ascii':
return asciiSlice(this, start, end)
case 'latin1':
case 'binary':
return latin1Slice(this, start, end)
case 'base64':
return base64Slice(this, start, end)
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return utf16leSlice(this, start, end)
default:
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
encoding = (encoding + '').toLowerCase()
loweredCase = true
}
}
}
// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect
// Buffer instances.
Buffer.prototype._isBuffer = true
function swap (b, n, m) {
var i = b[n]
b[n] = b[m]
b[m] = i
}
Buffer.prototype.swap16 = function swap16 () {
var len = this.length
if (len % 2 !== 0) {
throw new RangeError('Buffer size must be a multiple of 16-bits')
}
for (var i = 0; i < len; i += 2) {
swap(this, i, i + 1)
}
return this
}
Buffer.prototype.swap32 = function swap32 () {
var len = this.length
if (len % 4 !== 0) {
throw new RangeError('Buffer size must be a multiple of 32-bits')
}
for (var i = 0; i < len; i += 4) {
swap(this, i, i + 3)
swap(this, i + 1, i + 2)
}
return this
}
Buffer.prototype.swap64 = function swap64 () {
var len = this.length
if (len % 8 !== 0) {
throw new RangeError('Buffer size must be a multiple of 64-bits')
}
for (var i = 0; i < len; i += 8) {
swap(this, i, i + 7)
swap(this, i + 1, i + 6)
swap(this, i + 2, i + 5)
swap(this, i + 3, i + 4)
}
return this
}
Buffer.prototype.toString = function toString () {
var length = this.length | 0
if (length === 0) return ''
if (arguments.length === 0) return utf8Slice(this, 0, length)
return slowToString.apply(this, arguments)
}
Buffer.prototype.equals = function equals (b) {
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
if (this === b) return true
return Buffer.compare(this, b) === 0
}
Buffer.prototype.inspect = function inspect () {
var str = ''
var max = exports.INSPECT_MAX_BYTES
if (this.length > 0) {
str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
if (this.length > max) str += ' ... '
}
return '<Buffer ' + str + '>'
}
Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
if (!Buffer.isBuffer(target)) {
throw new TypeError('Argument must be a Buffer')
}
if (start === undefined) {
start = 0
}
if (end === undefined) {
end = target ? target.length : 0
}
if (thisStart === undefined) {
thisStart = 0
}
if (thisEnd === undefined) {
thisEnd = this.length
}
if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
throw new RangeError('out of range index')
}
if (thisStart >= thisEnd && start >= end) {
return 0
}
if (thisStart >= thisEnd) {
return -1
}
if (start >= end) {
return 1
}
start >>>= 0
end >>>= 0
thisStart >>>= 0
thisEnd >>>= 0
if (this === target) return 0
var x = thisEnd - thisStart
var y = end - start
var len = Math.min(x, y)
var thisCopy = this.slice(thisStart, thisEnd)
var targetCopy = target.slice(start, end)
for (var i = 0; i < len; ++i) {
if (thisCopy[i] !== targetCopy[i]) {
x = thisCopy[i]
y = targetCopy[i]
break
}
}
if (x < y) return -1
if (y < x) return 1
return 0
}
// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
//
// Arguments:
// - buffer - a Buffer to search
// - val - a string, Buffer, or number
// - byteOffset - an index into `buffer`; will be clamped to an int32
// - encoding - an optional encoding, relevant is val is a string
// - dir - true for indexOf, false for lastIndexOf
function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
// Empty buffer means no match
if (buffer.length === 0) return -1
// Normalize byteOffset
if (typeof byteOffset === 'string') {
encoding = byteOffset
byteOffset = 0
} else if (byteOffset > 0x7fffffff) {
byteOffset = 0x7fffffff
} else if (byteOffset < -0x80000000) {
byteOffset = -0x80000000
}
byteOffset = +byteOffset // Coerce to Number.
if (isNaN(byteOffset)) {
// byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
byteOffset = dir ? 0 : (buffer.length - 1)
}
// Normalize byteOffset: negative offsets start from the end of the buffer
if (byteOffset < 0) byteOffset = buffer.length + byteOffset
if (byteOffset >= buffer.length) {
if (dir) return -1
else byteOffset = buffer.length - 1
} else if (byteOffset < 0) {
if (dir) byteOffset = 0
else return -1
}
// Normalize val
if (typeof val === 'string') {
val = Buffer.from(val, encoding)
}
// Finally, search either indexOf (if dir is true) or lastIndexOf
if (Buffer.isBuffer(val)) {
// Special case: looking for empty string/buffer always fails
if (val.length === 0) {
return -1
}
return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
} else if (typeof val === 'number') {
val = val & 0xFF // Search for a byte value [0-255]
if (Buffer.TYPED_ARRAY_SUPPORT &&
typeof Uint8Array.prototype.indexOf === 'function') {
if (dir) {
return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
} else {
return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
}
}
return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
}
throw new TypeError('val must be string, number or Buffer')
}
function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
var indexSize = 1
var arrLength = arr.length
var valLength = val.length
if (encoding !== undefined) {
encoding = String(encoding).toLowerCase()
if (encoding === 'ucs2' || encoding === 'ucs-2' ||
encoding === 'utf16le' || encoding === 'utf-16le') {
if (arr.length < 2 || val.length < 2) {
return -1
}
indexSize = 2
arrLength /= 2
valLength /= 2
byteOffset /= 2
}
}
function read (buf, i) {
if (indexSize === 1) {
return buf[i]
} else {
return buf.readUInt16BE(i * indexSize)
}
}
var i
if (dir) {
var foundIndex = -1
for (i = byteOffset; i < arrLength; i++) {
if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
if (foundIndex === -1) foundIndex = i
if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
} else {
if (foundIndex !== -1) i -= i - foundIndex
foundIndex = -1
}
}
} else {
if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
for (i = byteOffset; i >= 0; i--) {
var found = true
for (var j = 0; j < valLength; j++) {
if (read(arr, i + j) !== read(val, j)) {
found = false
break
}
}
if (found) return i
}
}
return -1
}
Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
return this.indexOf(val, byteOffset, encoding) !== -1
}
Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
}
Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
}
function hexWrite (buf, string, offset, length) {
offset = Number(offset) || 0
var remaining = buf.length - offset
if (!length) {
length = remaining
} else {
length = Number(length)
if (length > remaining) {
length = remaining
}
}
// must be an even number of digits
var strLen = string.length
if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')
if (length > strLen / 2) {
length = strLen / 2
}
for (var i = 0; i < length; ++i) {
var parsed = parseInt(string.substr(i * 2, 2), 16)
if (isNaN(parsed)) return i
buf[offset + i] = parsed
}
return i
}
function utf8Write (buf, string, offset, length) {
return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
}
function asciiWrite (buf, string, offset, length) {
return blitBuffer(asciiToBytes(string), buf, offset, length)
}
function latin1Write (buf, string, offset, length) {
return asciiWrite(buf, string, offset, length)
}
function base64Write (buf, string, offset, length) {
return blitBuffer(base64ToBytes(string), buf, offset, length)
}
function ucs2Write (buf, string, offset, length) {
return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
}
Buffer.prototype.write = function write (string, offset, length, encoding) {
// Buffer#write(string)
if (offset === undefined) {
encoding = 'utf8'
length = this.length
offset = 0
// Buffer#write(string, encoding)
} else if (length === undefined && typeof offset === 'string') {
encoding = offset
length = this.length
offset = 0
// Buffer#write(string, offset[, length][, encoding])
} else if (isFinite(offset)) {
offset = offset | 0
if (isFinite(length)) {
length = length | 0
if (encoding === undefined) encoding = 'utf8'
} else {
encoding = length
length = undefined
}
// legacy write(string, encoding, offset, length) - remove in v0.13
} else {
throw new Error(
'Buffer.write(string, encoding, offset[, length]) is no longer supported'
)
}
var remaining = this.length - offset
if (length === undefined || length > remaining) length = remaining
if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
throw new RangeError('Attempt to write outside buffer bounds')
}
if (!encoding) encoding = 'utf8'
var loweredCase = false
for (;;) {
switch (encoding) {
case 'hex':
return hexWrite(this, string, offset, length)
case 'utf8':
case 'utf-8':
return utf8Write(this, string, offset, length)
case 'ascii':
return asciiWrite(this, string, offset, length)
case 'latin1':
case 'binary':
return latin1Write(this, string, offset, length)
case 'base64':
// Warning: maxLength not taken into account in base64Write
return base64Write(this, string, offset, length)
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return ucs2Write(this, string, offset, length)
default:
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
encoding = ('' + encoding).toLowerCase()
loweredCase = true
}
}
}
Buffer.prototype.toJSON = function toJSON () {
return {
type: 'Buffer',
data: Array.prototype.slice.call(this._arr || this, 0)
}
}
function base64Slice (buf, start, end) {
if (start === 0 && end === buf.length) {
return base64.fromByteArray(buf)
} else {
return base64.fromByteArray(buf.slice(start, end))
}
}
function utf8Slice (buf, start, end) {
end = Math.min(buf.length, end)
var res = []
var i = start
while (i < end) {
var firstByte = buf[i]
var codePoint = null
var bytesPerSequence = (firstByte > 0xEF) ? 4
: (firstByte > 0xDF) ? 3
: (firstByte > 0xBF) ? 2
: 1
if (i + bytesPerSequence <= end) {
var secondByte, thirdByte, fourthByte, tempCodePoint
switch (bytesPerSequence) {
case 1:
if (firstByte < 0x80) {
codePoint = firstByte
}
break
case 2:
secondByte = buf[i + 1]
if ((secondByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
if (tempCodePoint > 0x7F) {
codePoint = tempCodePoint
}
}
break
case 3:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
codePoint = tempCodePoint
}
}
break
case 4:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
fourthByte = buf[i + 3]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
codePoint = tempCodePoint
}
}
}
}
if (codePoint === null) {
// we did not generate a valid codePoint so insert a
// replacement char (U+FFFD) and advance only 1 byte
codePoint = 0xFFFD
bytesPerSequence = 1
} else if (codePoint > 0xFFFF) {
// encode to utf16 (surrogate pair dance)
codePoint -= 0x10000
res.push(codePoint >>> 10 & 0x3FF | 0xD800)
codePoint = 0xDC00 | codePoint & 0x3FF
}
res.push(codePoint)
i += bytesPerSequence
}
return decodeCodePointsArray(res)
}
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
// We go 1 magnitude less, for safety
var MAX_ARGUMENTS_LENGTH = 0x1000
function decodeCodePointsArray (codePoints) {
var len = codePoints.length
if (len <= MAX_ARGUMENTS_LENGTH) {
return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
}
// Decode in chunks to avoid "call stack size exceeded".
var res = ''
var i = 0
while (i < len) {
res += String.fromCharCode.apply(
String,
codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
)
}
return res
}
function asciiSlice (buf, start, end) {
var ret = ''
end = Math.min(buf.length, end)
for (var i = start; i < end; ++i) {
ret += String.fromCharCode(buf[i] & 0x7F)
}
return ret
}
function latin1Slice (buf, start, end) {
var ret = ''
end = Math.min(buf.length, end)
for (var i = start; i < end; ++i) {
ret += String.fromCharCode(buf[i])
}
return ret
}
function hexSlice (buf, start, end) {
var len = buf.length
if (!start || start < 0) start = 0
if (!end || end < 0 || end > len) end = len
var out = ''
for (var i = start; i < end; ++i) {
out += toHex(buf[i])
}
return out
}
function utf16leSlice (buf, start, end) {
var bytes = buf.slice(start, end)
var res = ''
for (var i = 0; i < bytes.length; i += 2) {
res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
}
return res
}
Buffer.prototype.slice = function slice (start, end) {
var len = this.length
start = ~~start
end = end === undefined ? len : ~~end
if (start < 0) {
start += len
if (start < 0) start = 0
} else if (start > len) {
start = len
}
if (end < 0) {
end += len
if (end < 0) end = 0
} else if (end > len) {
end = len
}
if (end < start) end = start
var newBuf
if (Buffer.TYPED_ARRAY_SUPPORT) {
newBuf = this.subarray(start, end)
newBuf.__proto__ = Buffer.prototype
} else {
var sliceLen = end - start
newBuf = new Buffer(sliceLen, undefined)
for (var i = 0; i < sliceLen; ++i) {
newBuf[i] = this[i + start]
}
}
return newBuf
}
/*
* Need to make sure that buffer isn't trying to write out of bounds.
*/
function checkOffset (offset, ext, length) {
if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
}
Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var val = this[offset]
var mul = 1
var i = 0
while (++i < byteLength && (mul *= 0x100)) {
val += this[offset + i] * mul
}
return val
}
Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) {
checkOffset(offset, byteLength, this.length)
}
var val = this[offset + --byteLength]
var mul = 1
while (byteLength > 0 && (mul *= 0x100)) {
val += this[offset + --byteLength] * mul
}
return val
}
Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
if (!noAssert) checkOffset(offset, 1, this.length)
return this[offset]
}
Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
return this[offset] | (this[offset + 1] << 8)
}
Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
return (this[offset] << 8) | this[offset + 1]
}
Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ((this[offset]) |
(this[offset + 1] << 8) |
(this[offset + 2] << 16)) +
(this[offset + 3] * 0x1000000)
}
Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset] * 0x1000000) +
((this[offset + 1] << 16) |
(this[offset + 2] << 8) |
this[offset + 3])
}
Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var val = this[offset]
var mul = 1
var i = 0
while (++i < byteLength && (mul *= 0x100)) {
val += this[offset + i] * mul
}
mul *= 0x80
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
return val
}
Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var i = byteLength
var mul = 1
var val = this[offset + --i]
while (i > 0 && (mul *= 0x100)) {
val += this[offset + --i] * mul
}
mul *= 0x80
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
return val
}
Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
if (!noAssert) checkOffset(offset, 1, this.length)
if (!(this[offset] & 0x80)) return (this[offset])
return ((0xff - this[offset] + 1) * -1)
}
Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
var val = this[offset] | (this[offset + 1] << 8)
return (val & 0x8000) ? val | 0xFFFF0000 : val
}
Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
var val = this[offset + 1] | (this[offset] << 8)
return (val & 0x8000) ? val | 0xFFFF0000 : val
}
Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset]) |
(this[offset + 1] << 8) |
(this[offset + 2] << 16) |
(this[offset + 3] << 24)
}
Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset] << 24) |
(this[offset + 1] << 16) |
(this[offset + 2] << 8) |
(this[offset + 3])
}
Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ieee754.read(this, offset, true, 23, 4)
}
Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ieee754.read(this, offset, false, 23, 4)
}
Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 8, this.length)
return ieee754.read(this, offset, true, 52, 8)
}
Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 8, this.length)
return ieee754.read(this, offset, false, 52, 8)
}
function checkInt (buf, value, offset, ext, max, min) {
if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
if (offset + ext > buf.length) throw new RangeError('Index out of range')
}
Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) {
var maxBytes = Math.pow(2, 8 * byteLength) - 1
checkInt(this, value, offset, byteLength, maxBytes, 0)
}
var mul = 1
var i = 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) {
var maxBytes = Math.pow(2, 8 * byteLength) - 1
checkInt(this, value, offset, byteLength, maxBytes, 0)
}
var i = byteLength - 1
var mul = 1
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
this[offset] = (value & 0xff)
return offset + 1
}
function objectWriteUInt16 (buf, value, offset, littleEndian) {
if (value < 0) value = 0xffff + value + 1
for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {
buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
(littleEndian ? i : 1 - i) * 8
}
}
Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
} else {
objectWriteUInt16(this, value, offset, true)
}
return offset + 2
}
Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 8)
this[offset + 1] = (value & 0xff)
} else {
objectWriteUInt16(this, value, offset, false)
}
return offset + 2
}
function objectWriteUInt32 (buf, value, offset, littleEndian) {
if (value < 0) value = 0xffffffff + value + 1
for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {
buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
}
}
Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset + 3] = (value >>> 24)
this[offset + 2] = (value >>> 16)
this[offset + 1] = (value >>> 8)
this[offset] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, true)
}
return offset + 4
}
Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 24)
this[offset + 1] = (value >>> 16)
this[offset + 2] = (value >>> 8)
this[offset + 3] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, false)
}
return offset + 4
}
Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) {
var limit = Math.pow(2, 8 * byteLength - 1)
checkInt(this, value, offset, byteLength, limit - 1, -limit)
}
var i = 0
var mul = 1
var sub = 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
sub = 1
}
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) {
var limit = Math.pow(2, 8 * byteLength - 1)
checkInt(this, value, offset, byteLength, limit - 1, -limit)
}
var i = byteLength - 1
var mul = 1
var sub = 0
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
sub = 1
}
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
if (value < 0) value = 0xff + value + 1
this[offset] = (value & 0xff)
return offset + 1
}
Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
} else {
objectWriteUInt16(this, value, offset, true)
}
return offset + 2
}
Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 8)
this[offset + 1] = (value & 0xff)
} else {
objectWriteUInt16(this, value, offset, false)
}
return offset + 2
}
Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
this[offset + 2] = (value >>> 16)
this[offset + 3] = (value >>> 24)
} else {
objectWriteUInt32(this, value, offset, true)
}
return offset + 4
}
Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
if (value < 0) value = 0xffffffff + value + 1
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 24)
this[offset + 1] = (value >>> 16)
this[offset + 2] = (value >>> 8)
this[offset + 3] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, false)
}
return offset + 4
}
function checkIEEE754 (buf, value, offset, ext, max, min) {
if (offset + ext > buf.length) throw new RangeError('Index out of range')
if (offset < 0) throw new RangeError('Index out of range')
}
function writeFloat (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
}
ieee754.write(buf, value, offset, littleEndian, 23, 4)
return offset + 4
}
Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
return writeFloat(this, value, offset, true, noAssert)
}
Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
return writeFloat(this, value, offset, false, noAssert)
}
function writeDouble (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
}
ieee754.write(buf, value, offset, littleEndian, 52, 8)
return offset + 8
}
Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
return writeDouble(this, value, offset, true, noAssert)
}
Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
return writeDouble(this, value, offset, false, noAssert)
}
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Buffer.prototype.copy = function copy (target, targetStart, start, end) {
if (!start) start = 0
if (!end && end !== 0) end = this.length
if (targetStart >= target.length) targetStart = target.length
if (!targetStart) targetStart = 0
if (end > 0 && end < start) end = start
// Copy 0 bytes; we're done
if (end === start) return 0
if (target.length === 0 || this.length === 0) return 0
// Fatal error conditions
if (targetStart < 0) {
throw new RangeError('targetStart out of bounds')
}
if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
if (end < 0) throw new RangeError('sourceEnd out of bounds')
// Are we oob?
if (end > this.length) end = this.length
if (target.length - targetStart < end - start) {
end = target.length - targetStart + start
}
var len = end - start
var i
if (this === target && start < targetStart && targetStart < end) {
// descending copy from end
for (i = len - 1; i >= 0; --i) {
target[i + targetStart] = this[i + start]
}
} else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
// ascending copy from start
for (i = 0; i < len; ++i) {
target[i + targetStart] = this[i + start]
}
} else {
Uint8Array.prototype.set.call(
target,
this.subarray(start, start + len),
targetStart
)
}
return len
}
// Usage:
// buffer.fill(number[, offset[, end]])
// buffer.fill(buffer[, offset[, end]])
// buffer.fill(string[, offset[, end]][, encoding])
Buffer.prototype.fill = function fill (val, start, end, encoding) {
// Handle string cases:
if (typeof val === 'string') {
if (typeof start === 'string') {
encoding = start
start = 0
end = this.length
} else if (typeof end === 'string') {
encoding = end
end = this.length
}
if (val.length === 1) {
var code = val.charCodeAt(0)
if (code < 256) {
val = code
}
}
if (encoding !== undefined && typeof encoding !== 'string') {
throw new TypeError('encoding must be a string')
}
if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
throw new TypeError('Unknown encoding: ' + encoding)
}
} else if (typeof val === 'number') {
val = val & 255
}
// Invalid ranges are not set to a default, so can range check early.
if (start < 0 || this.length < start || this.length < end) {
throw new RangeError('Out of range index')
}
if (end <= start) {
return this
}
start = start >>> 0
end = end === undefined ? this.length : end >>> 0
if (!val) val = 0
var i
if (typeof val === 'number') {
for (i = start; i < end; ++i) {
this[i] = val
}
} else {
var bytes = Buffer.isBuffer(val)
? val
: utf8ToBytes(new Buffer(val, encoding).toString())
var len = bytes.length
for (i = 0; i < end - start; ++i) {
this[i + start] = bytes[i % len]
}
}
return this
}
// HELPER FUNCTIONS
// ================
var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
function base64clean (str) {
// Node strips out invalid characters like \n and \t from the string, base64-js does not
str = stringtrim(str).replace(INVALID_BASE64_RE, '')
// Node converts strings with length < 2 to ''
if (str.length < 2) return ''
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
while (str.length % 4 !== 0) {
str = str + '='
}
return str
}
function stringtrim (str) {
if (str.trim) return str.trim()
return str.replace(/^\s+|\s+$/g, '')
}
function toHex (n) {
if (n < 16) return '0' + n.toString(16)
return n.toString(16)
}
function utf8ToBytes (string, units) {
units = units || Infinity
var codePoint
var length = string.length
var leadSurrogate = null
var bytes = []
for (var i = 0; i < length; ++i) {
codePoint = string.charCodeAt(i)
// is surrogate component
if (codePoint > 0xD7FF && codePoint < 0xE000) {
// last char was a lead
if (!leadSurrogate) {
// no lead yet
if (codePoint > 0xDBFF) {
// unexpected trail
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
} else if (i + 1 === length) {
// unpaired lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
}
// valid lead
leadSurrogate = codePoint
continue
}
// 2 leads in a row
if (codePoint < 0xDC00) {
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
leadSurrogate = codePoint
continue
}
// valid surrogate pair
codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
} else if (leadSurrogate) {
// valid bmp char, but last char was a lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
}
leadSurrogate = null
// encode utf8
if (codePoint < 0x80) {
if ((units -= 1) < 0) break
bytes.push(codePoint)
} else if (codePoint < 0x800) {
if ((units -= 2) < 0) break
bytes.push(
codePoint >> 0x6 | 0xC0,
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x10000) {
if ((units -= 3) < 0) break
bytes.push(
codePoint >> 0xC | 0xE0,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x110000) {
if ((units -= 4) < 0) break
bytes.push(
codePoint >> 0x12 | 0xF0,
codePoint >> 0xC & 0x3F | 0x80,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else {
throw new Error('Invalid code point')
}
}
return bytes
}
function asciiToBytes (str) {
var byteArray = []
for (var i = 0; i < str.length; ++i) {
// Node's code seems to be doing this and not & 0x7F..
byteArray.push(str.charCodeAt(i) & 0xFF)
}
return byteArray
}
function utf16leToBytes (str, units) {
var c, hi, lo
var byteArray = []
for (var i = 0; i < str.length; ++i) {
if ((units -= 2) < 0) break
c = str.charCodeAt(i)
hi = c >> 8
lo = c % 256
byteArray.push(lo)
byteArray.push(hi)
}
return byteArray
}
function base64ToBytes (str) {
return base64.toByteArray(base64clean(str))
}
function blitBuffer (src, dst, offset, length) {
for (var i = 0; i < length; ++i) {
if ((i + offset >= dst.length) || (i >= src.length)) break
dst[i + offset] = src[i]
}
return i
}
function isnan (val) {
return val !== val // eslint-disable-line no-self-compare
}
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ }),
/* 107 */
/***/ (function(module, exports) {
'use strict'
exports.byteLength = byteLength
exports.toByteArray = toByteArray
exports.fromByteArray = fromByteArray
var lookup = []
var revLookup = []
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
for (var i = 0, len = code.length; i < len; ++i) {
lookup[i] = code[i]
revLookup[code.charCodeAt(i)] = i
}
// Support decoding URL-safe base64 strings, as Node.js does.
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
revLookup['-'.charCodeAt(0)] = 62
revLookup['_'.charCodeAt(0)] = 63
function getLens (b64) {
var len = b64.length
if (len % 4 > 0) {
throw new Error('Invalid string. Length must be a multiple of 4')
}
// Trim off extra bytes after placeholder bytes are found
// See: https://github.com/beatgammit/base64-js/issues/42
var validLen = b64.indexOf('=')
if (validLen === -1) validLen = len
var placeHoldersLen = validLen === len
? 0
: 4 - (validLen % 4)
return [validLen, placeHoldersLen]
}
// base64 is 4/3 + up to two characters of the original data
function byteLength (b64) {
var lens = getLens(b64)
var validLen = lens[0]
var placeHoldersLen = lens[1]
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}
function _byteLength (b64, validLen, placeHoldersLen) {
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}
function toByteArray (b64) {
var tmp
var lens = getLens(b64)
var validLen = lens[0]
var placeHoldersLen = lens[1]
var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
var curByte = 0
// if there are placeholders, only get up to the last complete 4 chars
var len = placeHoldersLen > 0
? validLen - 4
: validLen
for (var i = 0; i < len; i += 4) {
tmp =
(revLookup[b64.charCodeAt(i)] << 18) |
(revLookup[b64.charCodeAt(i + 1)] << 12) |
(revLookup[b64.charCodeAt(i + 2)] << 6) |
revLookup[b64.charCodeAt(i + 3)]
arr[curByte++] = (tmp >> 16) & 0xFF
arr[curByte++] = (tmp >> 8) & 0xFF
arr[curByte++] = tmp & 0xFF
}
if (placeHoldersLen === 2) {
tmp =
(revLookup[b64.charCodeAt(i)] << 2) |
(revLookup[b64.charCodeAt(i + 1)] >> 4)
arr[curByte++] = tmp & 0xFF
}
if (placeHoldersLen === 1) {
tmp =
(revLookup[b64.charCodeAt(i)] << 10) |
(revLookup[b64.charCodeAt(i + 1)] << 4) |
(revLookup[b64.charCodeAt(i + 2)] >> 2)
arr[curByte++] = (tmp >> 8) & 0xFF
arr[curByte++] = tmp & 0xFF
}
return arr
}
function tripletToBase64 (num) {
return lookup[num >> 18 & 0x3F] +
lookup[num >> 12 & 0x3F] +
lookup[num >> 6 & 0x3F] +
lookup[num & 0x3F]
}
function encodeChunk (uint8, start, end) {
var tmp
var output = []
for (var i = start; i < end; i += 3) {
tmp =
((uint8[i] << 16) & 0xFF0000) +
((uint8[i + 1] << 8) & 0xFF00) +
(uint8[i + 2] & 0xFF)
output.push(tripletToBase64(tmp))
}
return output.join('')
}
function fromByteArray (uint8) {
var tmp
var len = uint8.length
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
var parts = []
var maxChunkLength = 16383 // must be multiple of 3
// go through the array every three bytes, we'll deal with trailing stuff later
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
parts.push(encodeChunk(
uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)
))
}
// pad the end with zeros, but make sure to not forget the extra bytes
if (extraBytes === 1) {
tmp = uint8[len - 1]
parts.push(
lookup[tmp >> 2] +
lookup[(tmp << 4) & 0x3F] +
'=='
)
} else if (extraBytes === 2) {
tmp = (uint8[len - 2] << 8) + uint8[len - 1]
parts.push(
lookup[tmp >> 10] +
lookup[(tmp >> 4) & 0x3F] +
lookup[(tmp << 2) & 0x3F] +
'='
)
}
return parts.join('')
}
/***/ }),
/* 108 */
/***/ (function(module, exports) {
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
var e, m
var eLen = (nBytes * 8) - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var nBits = -7
var i = isLE ? (nBytes - 1) : 0
var d = isLE ? -1 : 1
var s = buffer[offset + i]
i += d
e = s & ((1 << (-nBits)) - 1)
s >>= (-nBits)
nBits += eLen
for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
m = e & ((1 << (-nBits)) - 1)
e >>= (-nBits)
nBits += mLen
for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}
if (e === 0) {
e = 1 - eBias
} else if (e === eMax) {
return m ? NaN : ((s ? -1 : 1) * Infinity)
} else {
m = m + Math.pow(2, mLen)
e = e - eBias
}
return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
}
exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
var e, m, c
var eLen = (nBytes * 8) - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
var i = isLE ? 0 : (nBytes - 1)
var d = isLE ? 1 : -1
var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
value = Math.abs(value)
if (isNaN(value) || value === Infinity) {
m = isNaN(value) ? 1 : 0
e = eMax
} else {
e = Math.floor(Math.log(value) / Math.LN2)
if (value * (c = Math.pow(2, -e)) < 1) {
e--
c *= 2
}
if (e + eBias >= 1) {
value += rt / c
} else {
value += rt * Math.pow(2, 1 - eBias)
}
if (value * c >= 2) {
e++
c /= 2
}
if (e + eBias >= eMax) {
m = 0
e = eMax
} else if (e + eBias >= 1) {
m = ((value * c) - 1) * Math.pow(2, mLen)
e = e + eBias
} else {
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
e = 0
}
}
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
e = (e << mLen) | m
eLen += mLen
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
buffer[offset + i - d] |= s * 128
}
/***/ }),
/* 109 */
/***/ (function(module, exports) {
var toString = {}.toString;
module.exports = Array.isArray || function (arr) {
return toString.call(arr) == '[object Array]';
};
/***/ }),
/* 110 */
/***/ (function(module, exports) {
// shim for using process in browser
var process = module.exports = {};
// cached from whatever global is present so that test runners that stub it
// don't break things. But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals. It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout;
var cachedClearTimeout;
function defaultSetTimout() {
throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
throw new Error('clearTimeout has not been defined');
}
(function () {
try {
if (typeof setTimeout === 'function') {
cachedSetTimeout = setTimeout;
} else {
cachedSetTimeout = defaultSetTimout;
}
} catch (e) {
cachedSetTimeout = defaultSetTimout;
}
try {
if (typeof clearTimeout === 'function') {
cachedClearTimeout = clearTimeout;
} else {
cachedClearTimeout = defaultClearTimeout;
}
} catch (e) {
cachedClearTimeout = defaultClearTimeout;
}
} ())
function runTimeout(fun) {
if (cachedSetTimeout === setTimeout) {
//normal enviroments in sane situations
return setTimeout(fun, 0);
}
// if setTimeout wasn't available but was latter defined
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
cachedSetTimeout = setTimeout;
return setTimeout(fun, 0);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedSetTimeout(fun, 0);
} catch(e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedSetTimeout.call(null, fun, 0);
} catch(e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
return cachedSetTimeout.call(this, fun, 0);
}
}
}
function runClearTimeout(marker) {
if (cachedClearTimeout === clearTimeout) {
//normal enviroments in sane situations
return clearTimeout(marker);
}
// if clearTimeout wasn't available but was latter defined
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
cachedClearTimeout = clearTimeout;
return clearTimeout(marker);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedClearTimeout(marker);
} catch (e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedClearTimeout.call(null, marker);
} catch (e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
return cachedClearTimeout.call(this, marker);
}
}
}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
if (!draining || !currentQueue) {
return;
}
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = runTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
runClearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
runTimeout(drainQueue);
}
};
// v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;
process.listeners = function (name) { return [] }
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
/***/ }),
/* 111 */
/***/ (function(module, exports) {
/* (ignored) */
/***/ }),
/* 112 */
/***/ (function(module, exports) {
/* (ignored) */
/***/ }),
/* 113 */
/***/ (function(module, exports) {
/* (ignored) */
/***/ }),
/* 114 */
/***/ (function(module, exports, __webpack_require__) {
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
var punycode = __webpack_require__(115);
var util = __webpack_require__(117);
exports.parse = urlParse;
exports.resolve = urlResolve;
exports.resolveObject = urlResolveObject;
exports.format = urlFormat;
exports.Url = Url;
function Url() {
this.protocol = null;
this.slashes = null;
this.auth = null;
this.host = null;
this.port = null;
this.hostname = null;
this.hash = null;
this.search = null;
this.query = null;
this.pathname = null;
this.path = null;
this.href = null;
}
// Reference: RFC 3986, RFC 1808, RFC 2396
// define these here so at least they only have to be
// compiled once on the first module load.
var protocolPattern = /^([a-z0-9.+-]+:)/i,
portPattern = /:[0-9]*$/,
// Special case for a simple path URL
simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,
// RFC 2396: characters reserved for delimiting URLs.
// We actually just auto-escape these.
delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],
// RFC 2396: characters not allowed for various reasons.
unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),
// Allowed by RFCs, but cause of XSS attacks. Always escape these.
autoEscape = ['\''].concat(unwise),
// Characters that are never ever allowed in a hostname.
// Note that any invalid chars are also handled, but these
// are the ones that are *expected* to be seen, so we fast-path
// them.
nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
hostEndingChars = ['/', '?', '#'],
hostnameMaxLen = 255,
hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,
hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,
// protocols that can allow "unsafe" and "unwise" chars.
unsafeProtocol = {
'javascript': true,
'javascript:': true
},
// protocols that never have a hostname.
hostlessProtocol = {
'javascript': true,
'javascript:': true
},
// protocols that always contain a // bit.
slashedProtocol = {
'http': true,
'https': true,
'ftp': true,
'gopher': true,
'file': true,
'http:': true,
'https:': true,
'ftp:': true,
'gopher:': true,
'file:': true
},
querystring = __webpack_require__(118);
function urlParse(url, parseQueryString, slashesDenoteHost) {
if (url && util.isObject(url) && url instanceof Url) return url;
var u = new Url;
u.parse(url, parseQueryString, slashesDenoteHost);
return u;
}
Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
if (!util.isString(url)) {
throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
}
// Copy chrome, IE, opera backslash-handling behavior.
// Back slashes before the query string get converted to forward slashes
// See: https://code.google.com/p/chromium/issues/detail?id=25916
var queryIndex = url.indexOf('?'),
splitter =
(queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#',
uSplit = url.split(splitter),
slashRegex = /\\/g;
uSplit[0] = uSplit[0].replace(slashRegex, '/');
url = uSplit.join(splitter);
var rest = url;
// trim before proceeding.
// This is to support parse stuff like " http://foo.com \n"
rest = rest.trim();
if (!slashesDenoteHost && url.split('#').length === 1) {
// Try fast path regexp
var simplePath = simplePathPattern.exec(rest);
if (simplePath) {
this.path = rest;
this.href = rest;
this.pathname = simplePath[1];
if (simplePath[2]) {
this.search = simplePath[2];
if (parseQueryString) {
this.query = querystring.parse(this.search.substr(1));
} else {
this.query = this.search.substr(1);
}
} else if (parseQueryString) {
this.search = '';
this.query = {};
}
return this;
}
}
var proto = protocolPattern.exec(rest);
if (proto) {
proto = proto[0];
var lowerProto = proto.toLowerCase();
this.protocol = lowerProto;
rest = rest.substr(proto.length);
}
// figure out if it's got a host
// user@server is *always* interpreted as a hostname, and url
// resolution will treat //foo/bar as host=foo,path=bar because that's
// how the browser resolves relative URLs.
if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
var slashes = rest.substr(0, 2) === '//';
if (slashes && !(proto && hostlessProtocol[proto])) {
rest = rest.substr(2);
this.slashes = true;
}
}
if (!hostlessProtocol[proto] &&
(slashes || (proto && !slashedProtocol[proto]))) {
// there's a hostname.
// the first instance of /, ?, ;, or # ends the host.
//
// If there is an @ in the hostname, then non-host chars *are* allowed
// to the left of the last @ sign, unless some host-ending character
// comes *before* the @-sign.
// URLs are obnoxious.
//
// ex:
// http://a@b@c/ => user:a@b host:c
// http://a@b?@c => user:a host:c path:/?@c
// v0.12 TODO(isaacs): This is not quite how Chrome does things.
// Review our test case against browsers more comprehensively.
// find the first instance of any hostEndingChars
var hostEnd = -1;
for (var i = 0; i < hostEndingChars.length; i++) {
var hec = rest.indexOf(hostEndingChars[i]);
if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
hostEnd = hec;
}
// at this point, either we have an explicit point where the
// auth portion cannot go past, or the last @ char is the decider.
var auth, atSign;
if (hostEnd === -1) {
// atSign can be anywhere.
atSign = rest.lastIndexOf('@');
} else {
// atSign must be in auth portion.
// http://a@b/c@d => host:b auth:a path:/c@d
atSign = rest.lastIndexOf('@', hostEnd);
}
// Now we have a portion which is definitely the auth.
// Pull that off.
if (atSign !== -1) {
auth = rest.slice(0, atSign);
rest = rest.slice(atSign + 1);
this.auth = decodeURIComponent(auth);
}
// the host is the remaining to the left of the first non-host char
hostEnd = -1;
for (var i = 0; i < nonHostChars.length; i++) {
var hec = rest.indexOf(nonHostChars[i]);
if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
hostEnd = hec;
}
// if we still have not hit it, then the entire thing is a host.
if (hostEnd === -1)
hostEnd = rest.length;
this.host = rest.slice(0, hostEnd);
rest = rest.slice(hostEnd);
// pull out port.
this.parseHost();
// we've indicated that there is a hostname,
// so even if it's empty, it has to be present.
this.hostname = this.hostname || '';
// if hostname begins with [ and ends with ]
// assume that it's an IPv6 address.
var ipv6Hostname = this.hostname[0] === '[' &&
this.hostname[this.hostname.length - 1] === ']';
// validate a little.
if (!ipv6Hostname) {
var hostparts = this.hostname.split(/\./);
for (var i = 0, l = hostparts.length; i < l; i++) {
var part = hostparts[i];
if (!part) continue;
if (!part.match(hostnamePartPattern)) {
var newpart = '';
for (var j = 0, k = part.length; j < k; j++) {
if (part.charCodeAt(j) > 127) {
// we replace non-ASCII char with a temporary placeholder
// we need this to make sure size of hostname is not
// broken by replacing non-ASCII by nothing
newpart += 'x';
} else {
newpart += part[j];
}
}
// we test again with ASCII char only
if (!newpart.match(hostnamePartPattern)) {
var validParts = hostparts.slice(0, i);
var notHost = hostparts.slice(i + 1);
var bit = part.match(hostnamePartStart);
if (bit) {
validParts.push(bit[1]);
notHost.unshift(bit[2]);
}
if (notHost.length) {
rest = '/' + notHost.join('.') + rest;
}
this.hostname = validParts.join('.');
break;
}
}
}
}
if (this.hostname.length > hostnameMaxLen) {
this.hostname = '';
} else {
// hostnames are always lower case.
this.hostname = this.hostname.toLowerCase();
}
if (!ipv6Hostname) {
// IDNA Support: Returns a punycoded representation of "domain".
// It only converts parts of the domain name that
// have non-ASCII characters, i.e. it doesn't matter if
// you call it with a domain that already is ASCII-only.
this.hostname = punycode.toASCII(this.hostname);
}
var p = this.port ? ':' + this.port : '';
var h = this.hostname || '';
this.host = h + p;
this.href += this.host;
// strip [ and ] from the hostname
// the host field still retains them, though
if (ipv6Hostname) {
this.hostname = this.hostname.substr(1, this.hostname.length - 2);
if (rest[0] !== '/') {
rest = '/' + rest;
}
}
}
// now rest is set to the post-host stuff.
// chop off any delim chars.
if (!unsafeProtocol[lowerProto]) {
// First, make 100% sure that any "autoEscape" chars get
// escaped, even if encodeURIComponent doesn't think they
// need to be.
for (var i = 0, l = autoEscape.length; i < l; i++) {
var ae = autoEscape[i];
if (rest.indexOf(ae) === -1)
continue;
var esc = encodeURIComponent(ae);
if (esc === ae) {
esc = escape(ae);
}
rest = rest.split(ae).join(esc);
}
}
// chop off from the tail first.
var hash = rest.indexOf('#');
if (hash !== -1) {
// got a fragment string.
this.hash = rest.substr(hash);
rest = rest.slice(0, hash);
}
var qm = rest.indexOf('?');
if (qm !== -1) {
this.search = rest.substr(qm);
this.query = rest.substr(qm + 1);
if (parseQueryString) {
this.query = querystring.parse(this.query);
}
rest = rest.slice(0, qm);
} else if (parseQueryString) {
// no query string, but parseQueryString still requested
this.search = '';
this.query = {};
}
if (rest) this.pathname = rest;
if (slashedProtocol[lowerProto] &&
this.hostname && !this.pathname) {
this.pathname = '/';
}
//to support http.request
if (this.pathname || this.search) {
var p = this.pathname || '';
var s = this.search || '';
this.path = p + s;
}
// finally, reconstruct the href based on what has been validated.
this.href = this.format();
return this;
};
// format a parsed object into a url string
function urlFormat(obj) {
// ensure it's an object, and not a string url.
// If it's an obj, this is a no-op.
// this way, you can call url_format() on strings
// to clean up potentially wonky urls.
if (util.isString(obj)) obj = urlParse(obj);
if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
return obj.format();
}
Url.prototype.format = function() {
var auth = this.auth || '';
if (auth) {
auth = encodeURIComponent(auth);
auth = auth.replace(/%3A/i, ':');
auth += '@';
}
var protocol = this.protocol || '',
pathname = this.pathname || '',
hash = this.hash || '',
host = false,
query = '';
if (this.host) {
host = auth + this.host;
} else if (this.hostname) {
host = auth + (this.hostname.indexOf(':') === -1 ?
this.hostname :
'[' + this.hostname + ']');
if (this.port) {
host += ':' + this.port;
}
}
if (this.query &&
util.isObject(this.query) &&
Object.keys(this.query).length) {
query = querystring.stringify(this.query);
}
var search = this.search || (query && ('?' + query)) || '';
if (protocol && protocol.substr(-1) !== ':') protocol += ':';
// only the slashedProtocols get the //. Not mailto:, xmpp:, etc.
// unless they had them to begin with.
if (this.slashes ||
(!protocol || slashedProtocol[protocol]) && host !== false) {
host = '//' + (host || '');
if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
} else if (!host) {
host = '';
}
if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
if (search && search.charAt(0) !== '?') search = '?' + search;
pathname = pathname.replace(/[?#]/g, function(match) {
return encodeURIComponent(match);
});
search = search.replace('#', '%23');
return protocol + host + pathname + search + hash;
};
function urlResolve(source, relative) {
return urlParse(source, false, true).resolve(relative);
}
Url.prototype.resolve = function(relative) {
return this.resolveObject(urlParse(relative, false, true)).format();
};
function urlResolveObject(source, relative) {
if (!source) return relative;
return urlParse(source, false, true).resolveObject(relative);
}
Url.prototype.resolveObject = function(relative) {
if (util.isString(relative)) {
var rel = new Url();
rel.parse(relative, false, true);
relative = rel;
}
var result = new Url();
var tkeys = Object.keys(this);
for (var tk = 0; tk < tkeys.length; tk++) {
var tkey = tkeys[tk];
result[tkey] = this[tkey];
}
// hash is always overridden, no matter what.
// even href="" will remove it.
result.hash = relative.hash;
// if the relative url is empty, then there's nothing left to do here.
if (relative.href === '') {
result.href = result.format();
return result;
}
// hrefs like //foo/bar always cut to the protocol.
if (relative.slashes && !relative.protocol) {
// take everything except the protocol from relative
var rkeys = Object.keys(relative);
for (var rk = 0; rk < rkeys.length; rk++) {
var rkey = rkeys[rk];
if (rkey !== 'protocol')
result[rkey] = relative[rkey];
}
//urlParse appends trailing / to urls like http://www.example.com
if (slashedProtocol[result.protocol] &&
result.hostname && !result.pathname) {
result.path = result.pathname = '/';
}
result.href = result.format();
return result;
}
if (relative.protocol && relative.protocol !== result.protocol) {
// if it's a known url protocol, then changing
// the protocol does weird things
// first, if it's not file:, then we MUST have a host,
// and if there was a path
// to begin with, then we MUST have a path.
// if it is file:, then the host is dropped,
// because that's known to be hostless.
// anything else is assumed to be absolute.
if (!slashedProtocol[relative.protocol]) {
var keys = Object.keys(relative);
for (var v = 0; v < keys.length; v++) {
var k = keys[v];
result[k] = relative[k];
}
result.href = result.format();
return result;
}
result.protocol = relative.protocol;
if (!relative.host && !hostlessProtocol[relative.protocol]) {
var relPath = (relative.pathname || '').split('/');
while (relPath.length && !(relative.host = relPath.shift()));
if (!relative.host) relative.host = '';
if (!relative.hostname) relative.hostname = '';
if (relPath[0] !== '') relPath.unshift('');
if (relPath.length < 2) relPath.unshift('');
result.pathname = relPath.join('/');
} else {
result.pathname = relative.pathname;
}
result.search = relative.search;
result.query = relative.query;
result.host = relative.host || '';
result.auth = relative.auth;
result.hostname = relative.hostname || relative.host;
result.port = relative.port;
// to support http.request
if (result.pathname || result.search) {
var p = result.pathname || '';
var s = result.search || '';
result.path = p + s;
}
result.slashes = result.slashes || relative.slashes;
result.href = result.format();
return result;
}
var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
isRelAbs = (
relative.host ||
relative.pathname && relative.pathname.charAt(0) === '/'
),
mustEndAbs = (isRelAbs || isSourceAbs ||
(result.host && relative.pathname)),
removeAllDots = mustEndAbs,
srcPath = result.pathname && result.pathname.split('/') || [],
relPath = relative.pathname && relative.pathname.split('/') || [],
psychotic = result.protocol && !slashedProtocol[result.protocol];
// if the url is a non-slashed url, then relative
// links like ../.. should be able
// to crawl up to the hostname, as well. This is strange.
// result.protocol has already been set by now.
// Later on, put the first path part into the host field.
if (psychotic) {
result.hostname = '';
result.port = null;
if (result.host) {
if (srcPath[0] === '') srcPath[0] = result.host;
else srcPath.unshift(result.host);
}
result.host = '';
if (relative.protocol) {
relative.hostname = null;
relative.port = null;
if (relative.host) {
if (relPath[0] === '') relPath[0] = relative.host;
else relPath.unshift(relative.host);
}
relative.host = null;
}
mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
}
if (isRelAbs) {
// it's absolute.
result.host = (relative.host || relative.host === '') ?
relative.host : result.host;
result.hostname = (relative.hostname || relative.hostname === '') ?
relative.hostname : result.hostname;
result.search = relative.search;
result.query = relative.query;
srcPath = relPath;
// fall through to the dot-handling below.
} else if (relPath.length) {
// it's relative
// throw away the existing file, and take the new path instead.
if (!srcPath) srcPath = [];
srcPath.pop();
srcPath = srcPath.concat(relPath);
result.search = relative.search;
result.query = relative.query;
} else if (!util.isNullOrUndefined(relative.search)) {
// just pull out the search.
// like href='?foo'.
// Put this after the other two cases because it simplifies the booleans
if (psychotic) {
result.hostname = result.host = srcPath.shift();
//occationaly the auth can get stuck only in host
//this especially happens in cases like
//url.resolveObject('mailto:local1@domain1', 'local2@domain2')
var authInHost = result.host && result.host.indexOf('@') > 0 ?
result.host.split('@') : false;
if (authInHost) {
result.auth = authInHost.shift();
result.host = result.hostname = authInHost.shift();
}
}
result.search = relative.search;
result.query = relative.query;
//to support http.request
if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
result.path = (result.pathname ? result.pathname : '') +
(result.search ? result.search : '');
}
result.href = result.format();
return result;
}
if (!srcPath.length) {
// no path at all. easy.
// we've already handled the other stuff above.
result.pathname = null;
//to support http.request
if (result.search) {
result.path = '/' + result.search;
} else {
result.path = null;
}
result.href = result.format();
return result;
}
// if a url ENDs in . or .., then it must get a trailing slash.
// however, if it ends in anything else non-slashy,
// then it must NOT get a trailing slash.
var last = srcPath.slice(-1)[0];
var hasTrailingSlash = (
(result.host || relative.host || srcPath.length > 1) &&
(last === '.' || last === '..') || last === '');
// strip single dots, resolve double dots to parent dir
// if the path tries to go above the root, `up` ends up > 0
var up = 0;
for (var i = srcPath.length; i >= 0; i--) {
last = srcPath[i];
if (last === '.') {
srcPath.splice(i, 1);
} else if (last === '..') {
srcPath.splice(i, 1);
up++;
} else if (up) {
srcPath.splice(i, 1);
up--;
}
}
// if the path is allowed to go above the root, restore leading ..s
if (!mustEndAbs && !removeAllDots) {
for (; up--; up) {
srcPath.unshift('..');
}
}
if (mustEndAbs && srcPath[0] !== '' &&
(!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
srcPath.unshift('');
}
if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
srcPath.push('');
}
var isAbsolute = srcPath[0] === '' ||
(srcPath[0] && srcPath[0].charAt(0) === '/');
// put the host back
if (psychotic) {
result.hostname = result.host = isAbsolute ? '' :
srcPath.length ? srcPath.shift() : '';
//occationaly the auth can get stuck only in host
//this especially happens in cases like
//url.resolveObject('mailto:local1@domain1', 'local2@domain2')
var authInHost = result.host && result.host.indexOf('@') > 0 ?
result.host.split('@') : false;
if (authInHost) {
result.auth = authInHost.shift();
result.host = result.hostname = authInHost.shift();
}
}
mustEndAbs = mustEndAbs || (result.host && srcPath.length);
if (mustEndAbs && !isAbsolute) {
srcPath.unshift('');
}
if (!srcPath.length) {
result.pathname = null;
result.path = null;
} else {
result.pathname = srcPath.join('/');
}
//to support request.http
if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
result.path = (result.pathname ? result.pathname : '') +
(result.search ? result.search : '');
}
result.auth = relative.auth || result.auth;
result.slashes = result.slashes || relative.slashes;
result.href = result.format();
return result;
};
Url.prototype.parseHost = function() {
var host = this.host;
var port = portPattern.exec(host);
if (port) {
port = port[0];
if (port !== ':') {
this.port = port.substr(1);
}
host = host.substr(0, host.length - port.length);
}
if (host) this.hostname = host;
};
/***/ }),
/* 115 */
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, global) {/*! https://mths.be/punycode v1.3.2 by @mathias */
;(function(root) {
/** Detect free variables */
var freeExports = typeof exports == 'object' && exports &&
!exports.nodeType && exports;
var freeModule = typeof module == 'object' && module &&
!module.nodeType && module;
var freeGlobal = typeof global == 'object' && global;
if (
freeGlobal.global === freeGlobal ||
freeGlobal.window === freeGlobal ||
freeGlobal.self === freeGlobal
) {
root = freeGlobal;
}
/**
* The `punycode` object.
* @name punycode
* @type Object
*/
var punycode,
/** Highest positive signed 32-bit float value */
maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
/** Bootstring parameters */
base = 36,
tMin = 1,
tMax = 26,
skew = 38,
damp = 700,
initialBias = 72,
initialN = 128, // 0x80
delimiter = '-', // '\x2D'
/** Regular expressions */
regexPunycode = /^xn--/,
regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
/** Error messages */
errors = {
'overflow': 'Overflow: input needs wider integers to process',
'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
'invalid-input': 'Invalid input'
},
/** Convenience shortcuts */
baseMinusTMin = base - tMin,
floor = Math.floor,
stringFromCharCode = String.fromCharCode,
/** Temporary variable */
key;
/*--------------------------------------------------------------------------*/
/**
* A generic error utility function.
* @private
* @param {String} type The error type.
* @returns {Error} Throws a `RangeError` with the applicable error message.
*/
function error(type) {
throw RangeError(errors[type]);
}
/**
* A generic `Array#map` utility function.
* @private
* @param {Array} array The array to iterate over.
* @param {Function} callback The function that gets called for every array
* item.
* @returns {Array} A new array of values returned by the callback function.
*/
function map(array, fn) {
var length = array.length;
var result = [];
while (length--) {
result[length] = fn(array[length]);
}
return result;
}
/**
* A simple `Array#map`-like wrapper to work with domain name strings or email
* addresses.
* @private
* @param {String} domain The domain name or email address.
* @param {Function} callback The function that gets called for every
* character.
* @returns {Array} A new string of characters returned by the callback
* function.
*/
function mapDomain(string, fn) {
var parts = string.split('@');
var result = '';
if (parts.length > 1) {
// In email addresses, only the domain name should be punycoded. Leave
// the local part (i.e. everything up to `@`) intact.
result = parts[0] + '@';
string = parts[1];
}
// Avoid `split(regex)` for IE8 compatibility. See #17.
string = string.replace(regexSeparators, '\x2E');
var labels = string.split('.');
var encoded = map(labels, fn).join('.');
return result + encoded;
}
/**
* Creates an array containing the numeric code points of each Unicode
* character in the string. While JavaScript uses UCS-2 internally,
* this function will convert a pair of surrogate halves (each of which
* UCS-2 exposes as separate characters) into a single code point,
* matching UTF-16.
* @see `punycode.ucs2.encode`
* @see <https://mathiasbynens.be/notes/javascript-encoding>
* @memberOf punycode.ucs2
* @name decode
* @param {String} string The Unicode input string (UCS-2).
* @returns {Array} The new array of code points.
*/
function ucs2decode(string) {
var output = [],
counter = 0,
length = string.length,
value,
extra;
while (counter < length) {
value = string.charCodeAt(counter++);
if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
// high surrogate, and there is a next character
extra = string.charCodeAt(counter++);
if ((extra & 0xFC00) == 0xDC00) { // low surrogate
output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
} else {
// unmatched surrogate; only append this code unit, in case the next
// code unit is the high surrogate of a surrogate pair
output.push(value);
counter--;
}
} else {
output.push(value);
}
}
return output;
}
/**
* Creates a string based on an array of numeric code points.
* @see `punycode.ucs2.decode`
* @memberOf punycode.ucs2
* @name encode
* @param {Array} codePoints The array of numeric code points.
* @returns {String} The new Unicode string (UCS-2).
*/
function ucs2encode(array) {
return map(array, function(value) {
var output = '';
if (value > 0xFFFF) {
value -= 0x10000;
output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
value = 0xDC00 | value & 0x3FF;
}
output += stringFromCharCode(value);
return output;
}).join('');
}
/**
* Converts a basic code point into a digit/integer.
* @see `digitToBasic()`
* @private
* @param {Number} codePoint The basic numeric code point value.
* @returns {Number} The numeric value of a basic code point (for use in
* representing integers) in the range `0` to `base - 1`, or `base` if
* the code point does not represent a value.
*/
function basicToDigit(codePoint) {
if (codePoint - 48 < 10) {
return codePoint - 22;
}
if (codePoint - 65 < 26) {
return codePoint - 65;
}
if (codePoint - 97 < 26) {
return codePoint - 97;
}
return base;
}
/**
* Converts a digit/integer into a basic code point.
* @see `basicToDigit()`
* @private
* @param {Number} digit The numeric value of a basic code point.
* @returns {Number} The basic code point whose value (when used for
* representing integers) is `digit`, which needs to be in the range
* `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
* used; else, the lowercase form is used. The behavior is undefined
* if `flag` is non-zero and `digit` has no uppercase form.
*/
function digitToBasic(digit, flag) {
// 0..25 map to ASCII a..z or A..Z
// 26..35 map to ASCII 0..9
return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
}
/**
* Bias adaptation function as per section 3.4 of RFC 3492.
* http://tools.ietf.org/html/rfc3492#section-3.4
* @private
*/
function adapt(delta, numPoints, firstTime) {
var k = 0;
delta = firstTime ? floor(delta / damp) : delta >> 1;
delta += floor(delta / numPoints);
for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
delta = floor(delta / baseMinusTMin);
}
return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
}
/**
* Converts a Punycode string of ASCII-only symbols to a string of Unicode
* symbols.
* @memberOf punycode
* @param {String} input The Punycode string of ASCII-only symbols.
* @returns {String} The resulting string of Unicode symbols.
*/
function decode(input) {
// Don't use UCS-2
var output = [],
inputLength = input.length,
out,
i = 0,
n = initialN,
bias = initialBias,
basic,
j,
index,
oldi,
w,
k,
digit,
t,
/** Cached calculation results */
baseMinusT;
// Handle the basic code points: let `basic` be the number of input code
// points before the last delimiter, or `0` if there is none, then copy
// the first basic code points to the output.
basic = input.lastIndexOf(delimiter);
if (basic < 0) {
basic = 0;
}
for (j = 0; j < basic; ++j) {
// if it's not a basic code point
if (input.charCodeAt(j) >= 0x80) {
error('not-basic');
}
output.push(input.charCodeAt(j));
}
// Main decoding loop: start just after the last delimiter if any basic code
// points were copied; start at the beginning otherwise.
for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
// `index` is the index of the next character to be consumed.
// Decode a generalized variable-length integer into `delta`,
// which gets added to `i`. The overflow checking is easier
// if we increase `i` as we go, then subtract off its starting
// value at the end to obtain `delta`.
for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
if (index >= inputLength) {
error('invalid-input');
}
digit = basicToDigit(input.charCodeAt(index++));
if (digit >= base || digit > floor((maxInt - i) / w)) {
error('overflow');
}
i += digit * w;
t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
if (digit < t) {
break;
}
baseMinusT = base - t;
if (w > floor(maxInt / baseMinusT)) {
error('overflow');
}
w *= baseMinusT;
}
out = output.length + 1;
bias = adapt(i - oldi, out, oldi == 0);
// `i` was supposed to wrap around from `out` to `0`,
// incrementing `n` each time, so we'll fix that now:
if (floor(i / out) > maxInt - n) {
error('overflow');
}
n += floor(i / out);
i %= out;
// Insert `n` at position `i` of the output
output.splice(i++, 0, n);
}
return ucs2encode(output);
}
/**
* Converts a string of Unicode symbols (e.g. a domain name label) to a
* Punycode string of ASCII-only symbols.
* @memberOf punycode
* @param {String} input The string of Unicode symbols.
* @returns {String} The resulting Punycode string of ASCII-only symbols.
*/
function encode(input) {
var n,
delta,
handledCPCount,
basicLength,
bias,
j,
m,
q,
k,
t,
currentValue,
output = [],
/** `inputLength` will hold the number of code points in `input`. */
inputLength,
/** Cached calculation results */
handledCPCountPlusOne,
baseMinusT,
qMinusT;
// Convert the input in UCS-2 to Unicode
input = ucs2decode(input);
// Cache the length
inputLength = input.length;
// Initialize the state
n = initialN;
delta = 0;
bias = initialBias;
// Handle the basic code points
for (j = 0; j < inputLength; ++j) {
currentValue = input[j];
if (currentValue < 0x80) {
output.push(stringFromCharCode(currentValue));
}
}
handledCPCount = basicLength = output.length;
// `handledCPCount` is the number of code points that have been handled;
// `basicLength` is the number of basic code points.
// Finish the basic string - if it is not empty - with a delimiter
if (basicLength) {
output.push(delimiter);
}
// Main encoding loop:
while (handledCPCount < inputLength) {
// All non-basic code points < n have been handled already. Find the next
// larger one:
for (m = maxInt, j = 0; j < inputLength; ++j) {
currentValue = input[j];
if (currentValue >= n && currentValue < m) {
m = currentValue;
}
}
// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
// but guard against overflow
handledCPCountPlusOne = handledCPCount + 1;
if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
error('overflow');
}
delta += (m - n) * handledCPCountPlusOne;
n = m;
for (j = 0; j < inputLength; ++j) {
currentValue = input[j];
if (currentValue < n && ++delta > maxInt) {
error('overflow');
}
if (currentValue == n) {
// Represent delta as a generalized variable-length integer
for (q = delta, k = base; /* no condition */; k += base) {
t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
if (q < t) {
break;
}
qMinusT = q - t;
baseMinusT = base - t;
output.push(
stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
);
q = floor(qMinusT / baseMinusT);
}
output.push(stringFromCharCode(digitToBasic(q, 0)));
bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
delta = 0;
++handledCPCount;
}
}
++delta;
++n;
}
return output.join('');
}
/**
* Converts a Punycode string representing a domain name or an email address
* to Unicode. Only the Punycoded parts of the input will be converted, i.e.
* it doesn't matter if you call it on a string that has already been
* converted to Unicode.
* @memberOf punycode
* @param {String} input The Punycoded domain name or email address to
* convert to Unicode.
* @returns {String} The Unicode representation of the given Punycode
* string.
*/
function toUnicode(input) {
return mapDomain(input, function(string) {
return regexPunycode.test(string)
? decode(string.slice(4).toLowerCase())
: string;
});
}
/**
* Converts a Unicode string representing a domain name or an email address to
* Punycode. Only the non-ASCII parts of the domain name will be converted,
* i.e. it doesn't matter if you call it with a domain that's already in
* ASCII.
* @memberOf punycode
* @param {String} input The domain name or email address to convert, as a
* Unicode string.
* @returns {String} The Punycode representation of the given domain name or
* email address.
*/
function toASCII(input) {
return mapDomain(input, function(string) {
return regexNonASCII.test(string)
? 'xn--' + encode(string)
: string;
});
}
/*--------------------------------------------------------------------------*/
/** Define the public API */
punycode = {
/**
* A string representing the current Punycode.js version number.
* @memberOf punycode
* @type String
*/
'version': '1.3.2',
/**
* An object of methods to convert from JavaScript's internal character
* representation (UCS-2) to Unicode code points, and back.
* @see <https://mathiasbynens.be/notes/javascript-encoding>
* @memberOf punycode
* @type Object
*/
'ucs2': {
'decode': ucs2decode,
'encode': ucs2encode
},
'decode': decode,
'encode': encode,
'toASCII': toASCII,
'toUnicode': toUnicode
};
/** Expose `punycode` */
// Some AMD build optimizers, like r.js, check for specific condition patterns
// like the following:
if (
true
) {
!(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
return punycode;
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
} else if (freeExports && freeModule) {
if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+
freeModule.exports = punycode;
} else { // in Narwhal or RingoJS v0.7.0-
for (key in punycode) {
punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
}
}
} else { // in Rhino or a web browser
root.punycode = punycode;
}
}(this));
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(116)(module), (function() { return this; }())))
/***/ }),
/* 116 */
/***/ (function(module, exports) {
module.exports = function(module) {
if(!module.webpackPolyfill) {
module.deprecate = function() {};
module.paths = [];
// module.parent = undefined by default
module.children = [];
module.webpackPolyfill = 1;
}
return module;
}
/***/ }),
/* 117 */
/***/ (function(module, exports) {
'use strict';
module.exports = {
isString: function(arg) {
return typeof(arg) === 'string';
},
isObject: function(arg) {
return typeof(arg) === 'object' && arg !== null;
},
isNull: function(arg) {
return arg === null;
},
isNullOrUndefined: function(arg) {
return arg == null;
}
};
/***/ }),
/* 118 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
exports.decode = exports.parse = __webpack_require__(119);
exports.encode = exports.stringify = __webpack_require__(120);
/***/ }),
/* 119 */
/***/ (function(module, exports) {
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
// If obj.hasOwnProperty has been overridden, then calling
// obj.hasOwnProperty(prop) will break.
// See: https://github.com/joyent/node/issues/1707
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
module.exports = function(qs, sep, eq, options) {
sep = sep || '&';
eq = eq || '=';
var obj = {};
if (typeof qs !== 'string' || qs.length === 0) {
return obj;
}
var regexp = /\+/g;
qs = qs.split(sep);
var maxKeys = 1000;
if (options && typeof options.maxKeys === 'number') {
maxKeys = options.maxKeys;
}
var len = qs.length;
// maxKeys <= 0 means that we should not limit keys count
if (maxKeys > 0 && len > maxKeys) {
len = maxKeys;
}
for (var i = 0; i < len; ++i) {
var x = qs[i].replace(regexp, '%20'),
idx = x.indexOf(eq),
kstr, vstr, k, v;
if (idx >= 0) {
kstr = x.substr(0, idx);
vstr = x.substr(idx + 1);
} else {
kstr = x;
vstr = '';
}
k = decodeURIComponent(kstr);
v = decodeURIComponent(vstr);
if (!hasOwnProperty(obj, k)) {
obj[k] = v;
} else if (Array.isArray(obj[k])) {
obj[k].push(v);
} else {
obj[k] = [obj[k], v];
}
}
return obj;
};
/***/ }),
/* 120 */
/***/ (function(module, exports) {
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
var stringifyPrimitive = function(v) {
switch (typeof v) {
case 'string':
return v;
case 'boolean':
return v ? 'true' : 'false';
case 'number':
return isFinite(v) ? v : '';
default:
return '';
}
};
module.exports = function(obj, sep, eq, name) {
sep = sep || '&';
eq = eq || '=';
if (obj === null) {
obj = undefined;
}
if (typeof obj === 'object') {
return Object.keys(obj).map(function(k) {
var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
if (Array.isArray(obj[k])) {
return obj[k].map(function(v) {
return ks + encodeURIComponent(stringifyPrimitive(v));
}).join(sep);
} else {
return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
}
}).join(sep);
}
if (!name) return '';
return encodeURIComponent(stringifyPrimitive(name)) + eq +
encodeURIComponent(stringifyPrimitive(obj));
};
/***/ }),
/* 121 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {var ClientRequest = __webpack_require__(122)
var response = __webpack_require__(125)
var extend = __webpack_require__(146)
var statusCodes = __webpack_require__(147)
var url = __webpack_require__(114)
var http = exports
http.request = function (opts, cb) {
if (typeof opts === 'string')
opts = url.parse(opts)
else
opts = extend(opts)
// Normally, the page is loaded from http or https, so not specifying a protocol
// will result in a (valid) protocol-relative url. However, this won't work if
// the protocol is something else, like 'file:'
var defaultProtocol = global.location.protocol.search(/^https?:$/) === -1 ? 'http:' : ''
var protocol = opts.protocol || defaultProtocol
var host = opts.hostname || opts.host
var port = opts.port
var path = opts.path || '/'
// Necessary for IPv6 addresses
if (host && host.indexOf(':') !== -1)
host = '[' + host + ']'
// This may be a relative url. The browser should always be able to interpret it correctly.
opts.url = (host ? (protocol + '//' + host) : '') + (port ? ':' + port : '') + path
opts.method = (opts.method || 'GET').toUpperCase()
opts.headers = opts.headers || {}
// Also valid opts.auth, opts.mode
var req = new ClientRequest(opts)
if (cb)
req.on('response', cb)
return req
}
http.get = function get (opts, cb) {
var req = http.request(opts, cb)
req.end()
return req
}
http.ClientRequest = ClientRequest
http.IncomingMessage = response.IncomingMessage
http.Agent = function () {}
http.Agent.defaultMaxSockets = 4
http.globalAgent = new http.Agent()
http.STATUS_CODES = statusCodes
http.METHODS = [
'CHECKOUT',
'CONNECT',
'COPY',
'DELETE',
'GET',
'HEAD',
'LOCK',
'M-SEARCH',
'MERGE',
'MKACTIVITY',
'MKCOL',
'MOVE',
'NOTIFY',
'OPTIONS',
'PATCH',
'POST',
'PROPFIND',
'PROPPATCH',
'PURGE',
'PUT',
'REPORT',
'SEARCH',
'SUBSCRIBE',
'TRACE',
'UNLOCK',
'UNSUBSCRIBE'
]
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ }),
/* 122 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(Buffer, global, process) {var capability = __webpack_require__(123)
var inherits = __webpack_require__(124)
var response = __webpack_require__(125)
var stream = __webpack_require__(126)
var toArrayBuffer = __webpack_require__(145)
var IncomingMessage = response.IncomingMessage
var rStates = response.readyStates
function decideMode (preferBinary, useFetch) {
if (capability.fetch && useFetch) {
return 'fetch'
} else if (capability.mozchunkedarraybuffer) {
return 'moz-chunked-arraybuffer'
} else if (capability.msstream) {
return 'ms-stream'
} else if (capability.arraybuffer && preferBinary) {
return 'arraybuffer'
} else if (capability.vbArray && preferBinary) {
return 'text:vbarray'
} else {
return 'text'
}
}
var ClientRequest = module.exports = function (opts) {
var self = this
stream.Writable.call(self)
self._opts = opts
self._body = []
self._headers = {}
if (opts.auth)
self.setHeader('Authorization', 'Basic ' + new Buffer(opts.auth).toString('base64'))
Object.keys(opts.headers).forEach(function (name) {
self.setHeader(name, opts.headers[name])
})
var preferBinary
var useFetch = true
if (opts.mode === 'disable-fetch' || ('requestTimeout' in opts && !capability.abortController)) {
// If the use of XHR should be preferred. Not typically needed.
useFetch = false
preferBinary = true
} else if (opts.mode === 'prefer-streaming') {
// If streaming is a high priority but binary compatibility and
// the accuracy of the 'content-type' header aren't
preferBinary = false
} else if (opts.mode === 'allow-wrong-content-type') {
// If streaming is more important than preserving the 'content-type' header
preferBinary = !capability.overrideMimeType
} else if (!opts.mode || opts.mode === 'default' || opts.mode === 'prefer-fast') {
// Use binary if text streaming may corrupt data or the content-type header, or for speed
preferBinary = true
} else {
throw new Error('Invalid value for opts.mode')
}
self._mode = decideMode(preferBinary, useFetch)
self._fetchTimer = null
self.on('finish', function () {
self._onFinish()
})
}
inherits(ClientRequest, stream.Writable)
ClientRequest.prototype.setHeader = function (name, value) {
var self = this
var lowerName = name.toLowerCase()
// This check is not necessary, but it prevents warnings from browsers about setting unsafe
// headers. To be honest I'm not entirely sure hiding these warnings is a good thing, but
// http-browserify did it, so I will too.
if (unsafeHeaders.indexOf(lowerName) !== -1)
return
self._headers[lowerName] = {
name: name,
value: value
}
}
ClientRequest.prototype.getHeader = function (name) {
var header = this._headers[name.toLowerCase()]
if (header)
return header.value
return null
}
ClientRequest.prototype.removeHeader = function (name) {
var self = this
delete self._headers[name.toLowerCase()]
}
ClientRequest.prototype._onFinish = function () {
var self = this
if (self._destroyed)
return
var opts = self._opts
var headersObj = self._headers
var body = null
if (opts.method !== 'GET' && opts.method !== 'HEAD') {
if (capability.arraybuffer) {
body = toArrayBuffer(Buffer.concat(self._body))
} else if (capability.blobConstructor) {
body = new global.Blob(self._body.map(function (buffer) {
return toArrayBuffer(buffer)
}), {
type: (headersObj['content-type'] || {}).value || ''
})
} else {
// get utf8 string
body = Buffer.concat(self._body).toString()
}
}
// create flattened list of headers
var headersList = []
Object.keys(headersObj).forEach(function (keyName) {
var name = headersObj[keyName].name
var value = headersObj[keyName].value
if (Array.isArray(value)) {
value.forEach(function (v) {
headersList.push([name, v])
})
} else {
headersList.push([name, value])
}
})
if (self._mode === 'fetch') {
var signal = null
var fetchTimer = null
if (capability.abortController) {
var controller = new AbortController()
signal = controller.signal
self._fetchAbortController = controller
if ('requestTimeout' in opts && opts.requestTimeout !== 0) {
self._fetchTimer = global.setTimeout(function () {
self.emit('requestTimeout')
if (self._fetchAbortController)
self._fetchAbortController.abort()
}, opts.requestTimeout)
}
}
global.fetch(self._opts.url, {
method: self._opts.method,
headers: headersList,
body: body || undefined,
mode: 'cors',
credentials: opts.withCredentials ? 'include' : 'same-origin',
signal: signal
}).then(function (response) {
self._fetchResponse = response
self._connect()
}, function (reason) {
global.clearTimeout(self._fetchTimer)
if (!self._destroyed)
self.emit('error', reason)
})
} else {
var xhr = self._xhr = new global.XMLHttpRequest()
try {
xhr.open(self._opts.method, self._opts.url, true)
} catch (err) {
process.nextTick(function () {
self.emit('error', err)
})
return
}
// Can't set responseType on really old browsers
if ('responseType' in xhr)
xhr.responseType = self._mode.split(':')[0]
if ('withCredentials' in xhr)
xhr.withCredentials = !!opts.withCredentials
if (self._mode === 'text' && 'overrideMimeType' in xhr)
xhr.overrideMimeType('text/plain; charset=x-user-defined')
if ('requestTimeout' in opts) {
xhr.timeout = opts.requestTimeout
xhr.ontimeout = function () {
self.emit('requestTimeout')
}
}
headersList.forEach(function (header) {
xhr.setRequestHeader(header[0], header[1])
})
self._response = null
xhr.onreadystatechange = function () {
switch (xhr.readyState) {
case rStates.LOADING:
case rStates.DONE:
self._onXHRProgress()
break
}
}
// Necessary for streaming in Firefox, since xhr.response is ONLY defined
// in onprogress, not in onreadystatechange with xhr.readyState = 3
if (self._mode === 'moz-chunked-arraybuffer') {
xhr.onprogress = function () {
self._onXHRProgress()
}
}
xhr.onerror = function () {
if (self._destroyed)
return
self.emit('error', new Error('XHR error'))
}
try {
xhr.send(body)
} catch (err) {
process.nextTick(function () {
self.emit('error', err)
})
return
}
}
}
/**
* Checks if xhr.status is readable and non-zero, indicating no error.
* Even though the spec says it should be available in readyState 3,
* accessing it throws an exception in IE8
*/
function statusValid (xhr) {
try {
var status = xhr.status
return (status !== null && status !== 0)
} catch (e) {
return false
}
}
ClientRequest.prototype._onXHRProgress = function () {
var self = this
if (!statusValid(self._xhr) || self._destroyed)
return
if (!self._response)
self._connect()
self._response._onXHRProgress()
}
ClientRequest.prototype._connect = function () {
var self = this
if (self._destroyed)
return
self._response = new IncomingMessage(self._xhr, self._fetchResponse, self._mode, self._fetchTimer)
self._response.on('error', function(err) {
self.emit('error', err)
})
self.emit('response', self._response)
}
ClientRequest.prototype._write = function (chunk, encoding, cb) {
var self = this
self._body.push(chunk)
cb()
}
ClientRequest.prototype.abort = ClientRequest.prototype.destroy = function () {
var self = this
self._destroyed = true
global.clearTimeout(self._fetchTimer)
if (self._response)
self._response._destroyed = true
if (self._xhr)
self._xhr.abort()
else if (self._fetchAbortController)
self._fetchAbortController.abort()
}
ClientRequest.prototype.end = function (data, encoding, cb) {
var self = this
if (typeof data === 'function') {
cb = data
data = undefined
}
stream.Writable.prototype.end.call(self, data, encoding, cb)
}
ClientRequest.prototype.flushHeaders = function () {}
ClientRequest.prototype.setTimeout = function () {}
ClientRequest.prototype.setNoDelay = function () {}
ClientRequest.prototype.setSocketKeepAlive = function () {}
// Taken from http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader%28%29-method
var unsafeHeaders = [
'accept-charset',
'accept-encoding',
'access-control-request-headers',
'access-control-request-method',
'connection',
'content-length',
'cookie',
'cookie2',
'date',
'dnt',
'expect',
'host',
'keep-alive',
'origin',
'referer',
'te',
'trailer',
'transfer-encoding',
'upgrade',
'via'
]
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(106).Buffer, (function() { return this; }()), __webpack_require__(110)))
/***/ }),
/* 123 */
/***/ (function(module, exports) {
/* WEBPACK VAR INJECTION */(function(global) {exports.fetch = isFunction(global.fetch) && isFunction(global.ReadableStream)
exports.writableStream = isFunction(global.WritableStream)
exports.abortController = isFunction(global.AbortController)
exports.blobConstructor = false
try {
new Blob([new ArrayBuffer(1)])
exports.blobConstructor = true
} catch (e) {}
// The xhr request to example.com may violate some restrictive CSP configurations,
// so if we're running in a browser that supports `fetch`, avoid calling getXHR()
// and assume support for certain features below.
var xhr
function getXHR () {
// Cache the xhr value
if (xhr !== undefined) return xhr
if (global.XMLHttpRequest) {
xhr = new global.XMLHttpRequest()
// If XDomainRequest is available (ie only, where xhr might not work
// cross domain), use the page location. Otherwise use example.com
// Note: this doesn't actually make an http request.
try {
xhr.open('GET', global.XDomainRequest ? '/' : 'https://example.com')
} catch(e) {
xhr = null
}
} else {
// Service workers don't have XHR
xhr = null
}
return xhr
}
function checkTypeSupport (type) {
var xhr = getXHR()
if (!xhr) return false
try {
xhr.responseType = type
return xhr.responseType === type
} catch (e) {}
return false
}
// For some strange reason, Safari 7.0 reports typeof global.ArrayBuffer === 'object'.
// Safari 7.1 appears to have fixed this bug.
var haveArrayBuffer = typeof global.ArrayBuffer !== 'undefined'
var haveSlice = haveArrayBuffer && isFunction(global.ArrayBuffer.prototype.slice)
// If fetch is supported, then arraybuffer will be supported too. Skip calling
// checkTypeSupport(), since that calls getXHR().
exports.arraybuffer = exports.fetch || (haveArrayBuffer && checkTypeSupport('arraybuffer'))
// These next two tests unavoidably show warnings in Chrome. Since fetch will always
// be used if it's available, just return false for these to avoid the warnings.
exports.msstream = !exports.fetch && haveSlice && checkTypeSupport('ms-stream')
exports.mozchunkedarraybuffer = !exports.fetch && haveArrayBuffer &&
checkTypeSupport('moz-chunked-arraybuffer')
// If fetch is supported, then overrideMimeType will be supported too. Skip calling
// getXHR().
exports.overrideMimeType = exports.fetch || (getXHR() ? isFunction(getXHR().overrideMimeType) : false)
exports.vbArray = isFunction(global.VBArray)
function isFunction (value) {
return typeof value === 'function'
}
xhr = null // Help gc
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ }),
/* 124 */
/***/ (function(module, exports) {
if (typeof Object.create === 'function') {
// implementation from standard node.js 'util' module
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};
} else {
// old school shim for old browsers
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
var TempCtor = function () {}
TempCtor.prototype = superCtor.prototype
ctor.prototype = new TempCtor()
ctor.prototype.constructor = ctor
}
}
/***/ }),
/* 125 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(process, Buffer, global) {var capability = __webpack_require__(123)
var inherits = __webpack_require__(124)
var stream = __webpack_require__(126)
var rStates = exports.readyStates = {
UNSENT: 0,
OPENED: 1,
HEADERS_RECEIVED: 2,
LOADING: 3,
DONE: 4
}
var IncomingMessage = exports.IncomingMessage = function (xhr, response, mode, fetchTimer) {
var self = this
stream.Readable.call(self)
self._mode = mode
self.headers = {}
self.rawHeaders = []
self.trailers = {}
self.rawTrailers = []
// Fake the 'close' event, but only once 'end' fires
self.on('end', function () {
// The nextTick is necessary to prevent the 'request' module from causing an infinite loop
process.nextTick(function () {
self.emit('close')
})
})
if (mode === 'fetch') {
self._fetchResponse = response
self.url = response.url
self.statusCode = response.status
self.statusMessage = response.statusText
response.headers.forEach(function (header, key){
self.headers[key.toLowerCase()] = header
self.rawHeaders.push(key, header)
})
if (capability.writableStream) {
var writable = new WritableStream({
write: function (chunk) {
return new Promise(function (resolve, reject) {
if (self._destroyed) {
reject()
} else if(self.push(new Buffer(chunk))) {
resolve()
} else {
self._resumeFetch = resolve
}
})
},
close: function () {
global.clearTimeout(fetchTimer)
if (!self._destroyed)
self.push(null)
},
abort: function (err) {
if (!self._destroyed)
self.emit('error', err)
}
})
try {
response.body.pipeTo(writable).catch(function (err) {
global.clearTimeout(fetchTimer)
if (!self._destroyed)
self.emit('error', err)
})
return
} catch (e) {} // pipeTo method isn't defined. Can't find a better way to feature test this
}
// fallback for when writableStream or pipeTo aren't available
var reader = response.body.getReader()
function read () {
reader.read().then(function (result) {
if (self._destroyed)
return
if (result.done) {
global.clearTimeout(fetchTimer)
self.push(null)
return
}
self.push(new Buffer(result.value))
read()
}).catch(function (err) {
global.clearTimeout(fetchTimer)
if (!self._destroyed)
self.emit('error', err)
})
}
read()
} else {
self._xhr = xhr
self._pos = 0
self.url = xhr.responseURL
self.statusCode = xhr.status
self.statusMessage = xhr.statusText
var headers = xhr.getAllResponseHeaders().split(/\r?\n/)
headers.forEach(function (header) {
var matches = header.match(/^([^:]+):\s*(.*)/)
if (matches) {
var key = matches[1].toLowerCase()
if (key === 'set-cookie') {
if (self.headers[key] === undefined) {
self.headers[key] = []
}
self.headers[key].push(matches[2])
} else if (self.headers[key] !== undefined) {
self.headers[key] += ', ' + matches[2]
} else {
self.headers[key] = matches[2]
}
self.rawHeaders.push(matches[1], matches[2])
}
})
self._charset = 'x-user-defined'
if (!capability.overrideMimeType) {
var mimeType = self.rawHeaders['mime-type']
if (mimeType) {
var charsetMatch = mimeType.match(/;\s*charset=([^;])(;|$)/)
if (charsetMatch) {
self._charset = charsetMatch[1].toLowerCase()
}
}
if (!self._charset)
self._charset = 'utf-8' // best guess
}
}
}
inherits(IncomingMessage, stream.Readable)
IncomingMessage.prototype._read = function () {
var self = this
var resolve = self._resumeFetch
if (resolve) {
self._resumeFetch = null
resolve()
}
}
IncomingMessage.prototype._onXHRProgress = function () {
var self = this
var xhr = self._xhr
var response = null
switch (self._mode) {
case 'text:vbarray': // For IE9
if (xhr.readyState !== rStates.DONE)
break
try {
// This fails in IE8
response = new global.VBArray(xhr.responseBody).toArray()
} catch (e) {}
if (response !== null) {
self.push(new Buffer(response))
break
}
// Falls through in IE8
case 'text':
try { // This will fail when readyState = 3 in IE9. Switch mode and wait for readyState = 4
response = xhr.responseText
} catch (e) {
self._mode = 'text:vbarray'
break
}
if (response.length > self._pos) {
var newData = response.substr(self._pos)
if (self._charset === 'x-user-defined') {
var buffer = new Buffer(newData.length)
for (var i = 0; i < newData.length; i++)
buffer[i] = newData.charCodeAt(i) & 0xff
self.push(buffer)
} else {
self.push(newData, self._charset)
}
self._pos = response.length
}
break
case 'arraybuffer':
if (xhr.readyState !== rStates.DONE || !xhr.response)
break
response = xhr.response
self.push(new Buffer(new Uint8Array(response)))
break
case 'moz-chunked-arraybuffer': // take whole
response = xhr.response
if (xhr.readyState !== rStates.LOADING || !response)
break
self.push(new Buffer(new Uint8Array(response)))
break
case 'ms-stream':
response = xhr.response
if (xhr.readyState !== rStates.LOADING)
break
var reader = new global.MSStreamReader()
reader.onprogress = function () {
if (reader.result.byteLength > self._pos) {
self.push(new Buffer(new Uint8Array(reader.result.slice(self._pos))))
self._pos = reader.result.byteLength
}
}
reader.onload = function () {
self.push(null)
}
// reader.onerror = ??? // TODO: this
reader.readAsArrayBuffer(response)
break
}
// The ms-stream case handles end separately in reader.onload()
if (self._xhr.readyState === rStates.DONE && self._mode !== 'ms-stream') {
self.push(null)
}
}
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(110), __webpack_require__(106).Buffer, (function() { return this; }())))
/***/ }),
/* 126 */
/***/ (function(module, exports, __webpack_require__) {
exports = module.exports = __webpack_require__(127);
exports.Stream = exports;
exports.Readable = exports;
exports.Writable = __webpack_require__(138);
exports.Duplex = __webpack_require__(137);
exports.Transform = __webpack_require__(143);
exports.PassThrough = __webpack_require__(144);
/***/ }),
/* 127 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
/*<replacement>*/
var pna = __webpack_require__(128);
/*</replacement>*/
module.exports = Readable;
/*<replacement>*/
var isArray = __webpack_require__(109);
/*</replacement>*/
/*<replacement>*/
var Duplex;
/*</replacement>*/
Readable.ReadableState = ReadableState;
/*<replacement>*/
var EE = __webpack_require__(129).EventEmitter;
var EElistenerCount = function (emitter, type) {
return emitter.listeners(type).length;
};
/*</replacement>*/
/*<replacement>*/
var Stream = __webpack_require__(130);
/*</replacement>*/
/*<replacement>*/
var Buffer = __webpack_require__(131).Buffer;
var OurUint8Array = global.Uint8Array || function () {};
function _uint8ArrayToBuffer(chunk) {
return Buffer.from(chunk);
}
function _isUint8Array(obj) {
return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
}
/*</replacement>*/
/*<replacement>*/
var util = __webpack_require__(132);
util.inherits = __webpack_require__(124);
/*</replacement>*/
/*<replacement>*/
var debugUtil = __webpack_require__(133);
var debug = void 0;
if (debugUtil && debugUtil.debuglog) {
debug = debugUtil.debuglog('stream');
} else {
debug = function () {};
}
/*</replacement>*/
var BufferList = __webpack_require__(134);
var destroyImpl = __webpack_require__(136);
var StringDecoder;
util.inherits(Readable, Stream);
var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume'];
function prependListener(emitter, event, fn) {
// Sadly this is not cacheable as some libraries bundle their own
// event emitter implementation with them.
if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn);
// This is a hack to make sure that our error handler is attached before any
// userland ones. NEVER DO THIS. This is here only because this code needs
// to continue to work with older versions of Node.js that do not include
// the prependListener() method. The goal is to eventually remove this hack.
if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];
}
function ReadableState(options, stream) {
Duplex = Duplex || __webpack_require__(137);
options = options || {};
// Duplex streams are both readable and writable, but share
// the same options object.
// However, some cases require setting options to different
// values for the readable and the writable sides of the duplex stream.
// These options can be provided separately as readableXXX and writableXXX.
var isDuplex = stream instanceof Duplex;
// object stream flag. Used to make read(n) ignore n and to
// make all the buffer merging and length checks go away
this.objectMode = !!options.objectMode;
if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
// the point at which it stops calling _read() to fill the buffer
// Note: 0 is a valid value, means "don't call _read preemptively ever"
var hwm = options.highWaterMark;
var readableHwm = options.readableHighWaterMark;
var defaultHwm = this.objectMode ? 16 : 16 * 1024;
if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (readableHwm || readableHwm === 0)) this.highWaterMark = readableHwm;else this.highWaterMark = defaultHwm;
// cast to ints.
this.highWaterMark = Math.floor(this.highWaterMark);
// A linked list is used to store data chunks instead of an array because the
// linked list can remove elements from the beginning faster than
// array.shift()
this.buffer = new BufferList();
this.length = 0;
this.pipes = null;
this.pipesCount = 0;
this.flowing = null;
this.ended = false;
this.endEmitted = false;
this.reading = false;
// a flag to be able to tell if the event 'readable'/'data' is emitted
// immediately, or on a later tick. We set this to true at first, because
// any actions that shouldn't happen until "later" should generally also
// not happen before the first read call.
this.sync = true;
// whenever we return null, then we set a flag to say
// that we're awaiting a 'readable' event emission.
this.needReadable = false;
this.emittedReadable = false;
this.readableListening = false;
this.resumeScheduled = false;
// has it been destroyed
this.destroyed = false;
// Crypto is kind of old and crusty. Historically, its default string
// encoding is 'binary' so we have to make this configurable.
// Everything else in the universe uses 'utf8', though.
this.defaultEncoding = options.defaultEncoding || 'utf8';
// the number of writers that are awaiting a drain event in .pipe()s
this.awaitDrain = 0;
// if true, a maybeReadMore has been scheduled
this.readingMore = false;
this.decoder = null;
this.encoding = null;
if (options.encoding) {
if (!StringDecoder) StringDecoder = __webpack_require__(142).StringDecoder;
this.decoder = new StringDecoder(options.encoding);
this.encoding = options.encoding;
}
}
function Readable(options) {
Duplex = Duplex || __webpack_require__(137);
if (!(this instanceof Readable)) return new Readable(options);
this._readableState = new ReadableState(options, this);
// legacy
this.readable = true;
if (options) {
if (typeof options.read === 'function') this._read = options.read;
if (typeof options.destroy === 'function') this._destroy = options.destroy;
}
Stream.call(this);
}
Object.defineProperty(Readable.prototype, 'destroyed', {
get: function () {
if (this._readableState === undefined) {
return false;
}
return this._readableState.destroyed;
},
set: function (value) {
// we ignore the value if the stream
// has not been initialized yet
if (!this._readableState) {
return;
}
// backward compatibility, the user is explicitly
// managing destroyed
this._readableState.destroyed = value;
}
});
Readable.prototype.destroy = destroyImpl.destroy;
Readable.prototype._undestroy = destroyImpl.undestroy;
Readable.prototype._destroy = function (err, cb) {
this.push(null);
cb(err);
};
// Manually shove something into the read() buffer.
// This returns true if the highWaterMark has not been hit yet,
// similar to how Writable.write() returns true if you should
// write() some more.
Readable.prototype.push = function (chunk, encoding) {
var state = this._readableState;
var skipChunkCheck;
if (!state.objectMode) {
if (typeof chunk === 'string') {
encoding = encoding || state.defaultEncoding;
if (encoding !== state.encoding) {
chunk = Buffer.from(chunk, encoding);
encoding = '';
}
skipChunkCheck = true;
}
} else {
skipChunkCheck = true;
}
return readableAddChunk(this, chunk, encoding, false, skipChunkCheck);
};
// Unshift should *always* be something directly out of read()
Readable.prototype.unshift = function (chunk) {
return readableAddChunk(this, chunk, null, true, false);
};
function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) {
var state = stream._readableState;
if (chunk === null) {
state.reading = false;
onEofChunk(stream, state);
} else {
var er;
if (!skipChunkCheck) er = chunkInvalid(state, chunk);
if (er) {
stream.emit('error', er);
} else if (state.objectMode || chunk && chunk.length > 0) {
if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) {
chunk = _uint8ArrayToBuffer(chunk);
}
if (addToFront) {
if (state.endEmitted) stream.emit('error', new Error('stream.unshift() after end event'));else addChunk(stream, state, chunk, true);
} else if (state.ended) {
stream.emit('error', new Error('stream.push() after EOF'));
} else {
state.reading = false;
if (state.decoder && !encoding) {
chunk = state.decoder.write(chunk);
if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state);
} else {
addChunk(stream, state, chunk, false);
}
}
} else if (!addToFront) {
state.reading = false;
}
}
return needMoreData(state);
}
function addChunk(stream, state, chunk, addToFront) {
if (state.flowing && state.length === 0 && !state.sync) {
stream.emit('data', chunk);
stream.read(0);
} else {
// update the buffer info.
state.length += state.objectMode ? 1 : chunk.length;
if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
if (state.needReadable) emitReadable(stream);
}
maybeReadMore(stream, state);
}
function chunkInvalid(state, chunk) {
var er;
if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
er = new TypeError('Invalid non-string/buffer chunk');
}
return er;
}
// if it's past the high water mark, we can push in some more.
// Also, if we have no data yet, we can stand some
// more bytes. This is to work around cases where hwm=0,
// such as the repl. Also, if the push() triggered a
// readable event, and the user called read(largeNumber) such that
// needReadable was set, then we ought to push more, so that another
// 'readable' event will be triggered.
function needMoreData(state) {
return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);
}
Readable.prototype.isPaused = function () {
return this._readableState.flowing === false;
};
// backwards compatibility.
Readable.prototype.setEncoding = function (enc) {
if (!StringDecoder) StringDecoder = __webpack_require__(142).StringDecoder;
this._readableState.decoder = new StringDecoder(enc);
this._readableState.encoding = enc;
return this;
};
// Don't raise the hwm > 8MB
var MAX_HWM = 0x800000;
function computeNewHighWaterMark(n) {
if (n >= MAX_HWM) {
n = MAX_HWM;
} else {
// Get the next highest power of 2 to prevent increasing hwm excessively in
// tiny amounts
n--;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
n++;
}
return n;
}
// This function is designed to be inlinable, so please take care when making
// changes to the function body.
function howMuchToRead(n, state) {
if (n <= 0 || state.length === 0 && state.ended) return 0;
if (state.objectMode) return 1;
if (n !== n) {
// Only flow one buffer at a time
if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;
}
// If we're asking for more than the current hwm, then raise the hwm.
if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
if (n <= state.length) return n;
// Don't have enough
if (!state.ended) {
state.needReadable = true;
return 0;
}
return state.length;
}
// you can override either this method, or the async _read(n) below.
Readable.prototype.read = function (n) {
debug('read', n);
n = parseInt(n, 10);
var state = this._readableState;
var nOrig = n;
if (n !== 0) state.emittedReadable = false;
// if we're doing read(0) to trigger a readable event, but we
// already have a bunch of data in the buffer, then just trigger
// the 'readable' event and move on.
if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {
debug('read: emitReadable', state.length, state.ended);
if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
return null;
}
n = howMuchToRead(n, state);
// if we've ended, and we're now clear, then finish it up.
if (n === 0 && state.ended) {
if (state.length === 0) endReadable(this);
return null;
}
// All the actual chunk generation logic needs to be
// *below* the call to _read. The reason is that in certain
// synthetic stream cases, such as passthrough streams, _read
// may be a completely synchronous operation which may change
// the state of the read buffer, providing enough data when
// before there was *not* enough.
//
// So, the steps are:
// 1. Figure out what the state of things will be after we do
// a read from the buffer.
//
// 2. If that resulting state will trigger a _read, then call _read.
// Note that this may be asynchronous, or synchronous. Yes, it is
// deeply ugly to write APIs this way, but that still doesn't mean
// that the Readable class should behave improperly, as streams are
// designed to be sync/async agnostic.
// Take note if the _read call is sync or async (ie, if the read call
// has returned yet), so that we know whether or not it's safe to emit
// 'readable' etc.
//
// 3. Actually pull the requested chunks out of the buffer and return.
// if we need a readable event, then we need to do some reading.
var doRead = state.needReadable;
debug('need readable', doRead);
// if we currently have less than the highWaterMark, then also read some
if (state.length === 0 || state.length - n < state.highWaterMark) {
doRead = true;
debug('length less than watermark', doRead);
}
// however, if we've ended, then there's no point, and if we're already
// reading, then it's unnecessary.
if (state.ended || state.reading) {
doRead = false;
debug('reading or ended', doRead);
} else if (doRead) {
debug('do read');
state.reading = true;
state.sync = true;
// if the length is currently zero, then we *need* a readable event.
if (state.length === 0) state.needReadable = true;
// call internal read method
this._read(state.highWaterMark);
state.sync = false;
// If _read pushed data synchronously, then `reading` will be false,
// and we need to re-evaluate how much data we can return to the user.
if (!state.reading) n = howMuchToRead(nOrig, state);
}
var ret;
if (n > 0) ret = fromList(n, state);else ret = null;
if (ret === null) {
state.needReadable = true;
n = 0;
} else {
state.length -= n;
}
if (state.length === 0) {
// If we have nothing in the buffer, then we want to know
// as soon as we *do* get something into the buffer.
if (!state.ended) state.needReadable = true;
// If we tried to read() past the EOF, then emit end on the next tick.
if (nOrig !== n && state.ended) endReadable(this);
}
if (ret !== null) this.emit('data', ret);
return ret;
};
function onEofChunk(stream, state) {
if (state.ended) return;
if (state.decoder) {
var chunk = state.decoder.end();
if (chunk && chunk.length) {
state.buffer.push(chunk);
state.length += state.objectMode ? 1 : chunk.length;
}
}
state.ended = true;
// emit 'readable' now to make sure it gets picked up.
emitReadable(stream);
}
// Don't emit readable right away in sync mode, because this can trigger
// another read() call => stack overflow. This way, it might trigger
// a nextTick recursion warning, but that's not so bad.
function emitReadable(stream) {
var state = stream._readableState;
state.needReadable = false;
if (!state.emittedReadable) {
debug('emitReadable', state.flowing);
state.emittedReadable = true;
if (state.sync) pna.nextTick(emitReadable_, stream);else emitReadable_(stream);
}
}
function emitReadable_(stream) {
debug('emit readable');
stream.emit('readable');
flow(stream);
}
// at this point, the user has presumably seen the 'readable' event,
// and called read() to consume some data. that may have triggered
// in turn another _read(n) call, in which case reading = true if
// it's in progress.
// However, if we're not ended, or reading, and the length < hwm,
// then go ahead and try to read some more preemptively.
function maybeReadMore(stream, state) {
if (!state.readingMore) {
state.readingMore = true;
pna.nextTick(maybeReadMore_, stream, state);
}
}
function maybeReadMore_(stream, state) {
var len = state.length;
while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {
debug('maybeReadMore read 0');
stream.read(0);
if (len === state.length)
// didn't get any data, stop spinning.
break;else len = state.length;
}
state.readingMore = false;
}
// abstract method. to be overridden in specific implementation classes.
// call cb(er, data) where data is <= n in length.
// for virtual (non-string, non-buffer) streams, "length" is somewhat
// arbitrary, and perhaps not very meaningful.
Readable.prototype._read = function (n) {
this.emit('error', new Error('_read() is not implemented'));
};
Readable.prototype.pipe = function (dest, pipeOpts) {
var src = this;
var state = this._readableState;
switch (state.pipesCount) {
case 0:
state.pipes = dest;
break;
case 1:
state.pipes = [state.pipes, dest];
break;
default:
state.pipes.push(dest);
break;
}
state.pipesCount += 1;
debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
var endFn = doEnd ? onend : unpipe;
if (state.endEmitted) pna.nextTick(endFn);else src.once('end', endFn);
dest.on('unpipe', onunpipe);
function onunpipe(readable, unpipeInfo) {
debug('onunpipe');
if (readable === src) {
if (unpipeInfo && unpipeInfo.hasUnpiped === false) {
unpipeInfo.hasUnpiped = true;
cleanup();
}
}
}
function onend() {
debug('onend');
dest.end();
}
// when the dest drains, it reduces the awaitDrain counter
// on the source. This would be more elegant with a .once()
// handler in flow(), but adding and removing repeatedly is
// too slow.
var ondrain = pipeOnDrain(src);
dest.on('drain', ondrain);
var cleanedUp = false;
function cleanup() {
debug('cleanup');
// cleanup event handlers once the pipe is broken
dest.removeListener('close', onclose);
dest.removeListener('finish', onfinish);
dest.removeListener('drain', ondrain);
dest.removeListener('error', onerror);
dest.removeListener('unpipe', onunpipe);
src.removeListener('end', onend);
src.removeListener('end', unpipe);
src.removeListener('data', ondata);
cleanedUp = true;
// if the reader is waiting for a drain event from this
// specific writer, then it would cause it to never start
// flowing again.
// So, if this is awaiting a drain, then we just call it now.
// If we don't know, then assume that we are waiting for one.
if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
}
// If the user pushes more data while we're writing to dest then we'll end up
// in ondata again. However, we only want to increase awaitDrain once because
// dest will only emit one 'drain' event for the multiple writes.
// => Introduce a guard on increasing awaitDrain.
var increasedAwaitDrain = false;
src.on('data', ondata);
function ondata(chunk) {
debug('ondata');
increasedAwaitDrain = false;
var ret = dest.write(chunk);
if (false === ret && !increasedAwaitDrain) {
// If the user unpiped during `dest.write()`, it is possible
// to get stuck in a permanently paused state if that write
// also returned false.
// => Check whether `dest` is still a piping destination.
if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {
debug('false write response, pause', src._readableState.awaitDrain);
src._readableState.awaitDrain++;
increasedAwaitDrain = true;
}
src.pause();
}
}
// if the dest has an error, then stop piping into it.
// however, don't suppress the throwing behavior for this.
function onerror(er) {
debug('onerror', er);
unpipe();
dest.removeListener('error', onerror);
if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);
}
// Make sure our error handler is attached before userland ones.
prependListener(dest, 'error', onerror);
// Both close and finish should trigger unpipe, but only once.
function onclose() {
dest.removeListener('finish', onfinish);
unpipe();
}
dest.once('close', onclose);
function onfinish() {
debug('onfinish');
dest.removeListener('close', onclose);
unpipe();
}
dest.once('finish', onfinish);
function unpipe() {
debug('unpipe');
src.unpipe(dest);
}
// tell the dest that it's being piped to
dest.emit('pipe', src);
// start the flow if it hasn't been started already.
if (!state.flowing) {
debug('pipe resume');
src.resume();
}
return dest;
};
function pipeOnDrain(src) {
return function () {
var state = src._readableState;
debug('pipeOnDrain', state.awaitDrain);
if (state.awaitDrain) state.awaitDrain--;
if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
state.flowing = true;
flow(src);
}
};
}
Readable.prototype.unpipe = function (dest) {
var state = this._readableState;
var unpipeInfo = { hasUnpiped: false };
// if we're not piping anywhere, then do nothing.
if (state.pipesCount === 0) return this;
// just one destination. most common case.
if (state.pipesCount === 1) {
// passed in one, but it's not the right one.
if (dest && dest !== state.pipes) return this;
if (!dest) dest = state.pipes;
// got a match.
state.pipes = null;
state.pipesCount = 0;
state.flowing = false;
if (dest) dest.emit('unpipe', this, unpipeInfo);
return this;
}
// slow case. multiple pipe destinations.
if (!dest) {
// remove all.
var dests = state.pipes;
var len = state.pipesCount;
state.pipes = null;
state.pipesCount = 0;
state.flowing = false;
for (var i = 0; i < len; i++) {
dests[i].emit('unpipe', this, unpipeInfo);
}return this;
}
// try to find the right one.
var index = indexOf(state.pipes, dest);
if (index === -1) return this;
state.pipes.splice(index, 1);
state.pipesCount -= 1;
if (state.pipesCount === 1) state.pipes = state.pipes[0];
dest.emit('unpipe', this, unpipeInfo);
return this;
};
// set up data events if they are asked for
// Ensure readable listeners eventually get something
Readable.prototype.on = function (ev, fn) {
var res = Stream.prototype.on.call(this, ev, fn);
if (ev === 'data') {
// Start flowing on next tick if stream isn't explicitly paused
if (this._readableState.flowing !== false) this.resume();
} else if (ev === 'readable') {
var state = this._readableState;
if (!state.endEmitted && !state.readableListening) {
state.readableListening = state.needReadable = true;
state.emittedReadable = false;
if (!state.reading) {
pna.nextTick(nReadingNextTick, this);
} else if (state.length) {
emitReadable(this);
}
}
}
return res;
};
Readable.prototype.addListener = Readable.prototype.on;
function nReadingNextTick(self) {
debug('readable nexttick read 0');
self.read(0);
}
// pause() and resume() are remnants of the legacy readable stream API
// If the user uses them, then switch into old mode.
Readable.prototype.resume = function () {
var state = this._readableState;
if (!state.flowing) {
debug('resume');
state.flowing = true;
resume(this, state);
}
return this;
};
function resume(stream, state) {
if (!state.resumeScheduled) {
state.resumeScheduled = true;
pna.nextTick(resume_, stream, state);
}
}
function resume_(stream, state) {
if (!state.reading) {
debug('resume read 0');
stream.read(0);
}
state.resumeScheduled = false;
state.awaitDrain = 0;
stream.emit('resume');
flow(stream);
if (state.flowing && !state.reading) stream.read(0);
}
Readable.prototype.pause = function () {
debug('call pause flowing=%j', this._readableState.flowing);
if (false !== this._readableState.flowing) {
debug('pause');
this._readableState.flowing = false;
this.emit('pause');
}
return this;
};
function flow(stream) {
var state = stream._readableState;
debug('flow', state.flowing);
while (state.flowing && stream.read() !== null) {}
}
// wrap an old-style stream as the async data source.
// This is *not* part of the readable stream interface.
// It is an ugly unfortunate mess of history.
Readable.prototype.wrap = function (stream) {
var _this = this;
var state = this._readableState;
var paused = false;
stream.on('end', function () {
debug('wrapped end');
if (state.decoder && !state.ended) {
var chunk = state.decoder.end();
if (chunk && chunk.length) _this.push(chunk);
}
_this.push(null);
});
stream.on('data', function (chunk) {
debug('wrapped data');
if (state.decoder) chunk = state.decoder.write(chunk);
// don't skip over falsy values in objectMode
if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
var ret = _this.push(chunk);
if (!ret) {
paused = true;
stream.pause();
}
});
// proxy all the other methods.
// important when wrapping filters and duplexes.
for (var i in stream) {
if (this[i] === undefined && typeof stream[i] === 'function') {
this[i] = function (method) {
return function () {
return stream[method].apply(stream, arguments);
};
}(i);
}
}
// proxy certain important events.
for (var n = 0; n < kProxyEvents.length; n++) {
stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n]));
}
// when we try to consume some more bytes, simply unpause the
// underlying stream.
this._read = function (n) {
debug('wrapped _read', n);
if (paused) {
paused = false;
stream.resume();
}
};
return this;
};
Object.defineProperty(Readable.prototype, 'readableHighWaterMark', {
// making it explicit this property is not enumerable
// because otherwise some prototype manipulation in
// userland will fail
enumerable: false,
get: function () {
return this._readableState.highWaterMark;
}
});
// exposed for testing purposes only.
Readable._fromList = fromList;
// Pluck off n bytes from an array of buffers.
// Length is the combined lengths of all the buffers in the list.
// This function is designed to be inlinable, so please take care when making
// changes to the function body.
function fromList(n, state) {
// nothing buffered
if (state.length === 0) return null;
var ret;
if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {
// read it all, truncate the list
if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length);
state.buffer.clear();
} else {
// read part of list
ret = fromListPartial(n, state.buffer, state.decoder);
}
return ret;
}
// Extracts only enough buffered data to satisfy the amount requested.
// This function is designed to be inlinable, so please take care when making
// changes to the function body.
function fromListPartial(n, list, hasStrings) {
var ret;
if (n < list.head.data.length) {
// slice is the same for buffers and strings
ret = list.head.data.slice(0, n);
list.head.data = list.head.data.slice(n);
} else if (n === list.head.data.length) {
// first chunk is a perfect match
ret = list.shift();
} else {
// result spans more than one buffer
ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);
}
return ret;
}
// Copies a specified amount of characters from the list of buffered data
// chunks.
// This function is designed to be inlinable, so please take care when making
// changes to the function body.
function copyFromBufferString(n, list) {
var p = list.head;
var c = 1;
var ret = p.data;
n -= ret.length;
while (p = p.next) {
var str = p.data;
var nb = n > str.length ? str.length : n;
if (nb === str.length) ret += str;else ret += str.slice(0, n);
n -= nb;
if (n === 0) {
if (nb === str.length) {
++c;
if (p.next) list.head = p.next;else list.head = list.tail = null;
} else {
list.head = p;
p.data = str.slice(nb);
}
break;
}
++c;
}
list.length -= c;
return ret;
}
// Copies a specified amount of bytes from the list of buffered data chunks.
// This function is designed to be inlinable, so please take care when making
// changes to the function body.
function copyFromBuffer(n, list) {
var ret = Buffer.allocUnsafe(n);
var p = list.head;
var c = 1;
p.data.copy(ret);
n -= p.data.length;
while (p = p.next) {
var buf = p.data;
var nb = n > buf.length ? buf.length : n;
buf.copy(ret, ret.length - n, 0, nb);
n -= nb;
if (n === 0) {
if (nb === buf.length) {
++c;
if (p.next) list.head = p.next;else list.head = list.tail = null;
} else {
list.head = p;
p.data = buf.slice(nb);
}
break;
}
++c;
}
list.length -= c;
return ret;
}
function endReadable(stream) {
var state = stream._readableState;
// If we get here before consuming all the bytes, then that is a
// bug in node. Should never happen.
if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream');
if (!state.endEmitted) {
state.ended = true;
pna.nextTick(endReadableNT, state, stream);
}
}
function endReadableNT(state, stream) {
// Check that we didn't get one last unshift.
if (!state.endEmitted && state.length === 0) {
state.endEmitted = true;
stream.readable = false;
stream.emit('end');
}
}
function indexOf(xs, x) {
for (var i = 0, l = xs.length; i < l; i++) {
if (xs[i] === x) return i;
}
return -1;
}
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(110)))
/***/ }),
/* 128 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(process) {'use strict';
if (!process.version ||
process.version.indexOf('v0.') === 0 ||
process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
module.exports = { nextTick: nextTick };
} else {
module.exports = process
}
function nextTick(fn, arg1, arg2, arg3) {
if (typeof fn !== 'function') {
throw new TypeError('"callback" argument must be a function');
}
var len = arguments.length;
var args, i;
switch (len) {
case 0:
case 1:
return process.nextTick(fn);
case 2:
return process.nextTick(function afterTickOne() {
fn.call(null, arg1);
});
case 3:
return process.nextTick(function afterTickTwo() {
fn.call(null, arg1, arg2);
});
case 4:
return process.nextTick(function afterTickThree() {
fn.call(null, arg1, arg2, arg3);
});
default:
args = new Array(len - 1);
i = 0;
while (i < args.length) {
args[i++] = arguments[i];
}
return process.nextTick(function afterTick() {
fn.apply(null, args);
});
}
}
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(110)))
/***/ }),
/* 129 */
/***/ (function(module, exports) {
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
function EventEmitter() {
this._events = this._events || {};
this._maxListeners = this._maxListeners || undefined;
}
module.exports = EventEmitter;
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._maxListeners = undefined;
// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
EventEmitter.defaultMaxListeners = 10;
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function(n) {
if (!isNumber(n) || n < 0 || isNaN(n))
throw TypeError('n must be a positive number');
this._maxListeners = n;
return this;
};
EventEmitter.prototype.emit = function(type) {
var er, handler, len, args, i, listeners;
if (!this._events)
this._events = {};
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events.error ||
(isObject(this._events.error) && !this._events.error.length)) {
er = arguments[1];
if (er instanceof Error) {
throw er; // Unhandled 'error' event
} else {
// At least give some kind of context to the user
var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
err.context = er;
throw err;
}
}
}
handler = this._events[type];
if (isUndefined(handler))
return false;
if (isFunction(handler)) {
switch (arguments.length) {
// fast cases
case 1:
handler.call(this);
break;
case 2:
handler.call(this, arguments[1]);
break;
case 3:
handler.call(this, arguments[1], arguments[2]);
break;
// slower
default:
args = Array.prototype.slice.call(arguments, 1);
handler.apply(this, args);
}
} else if (isObject(handler)) {
args = Array.prototype.slice.call(arguments, 1);
listeners = handler.slice();
len = listeners.length;
for (i = 0; i < len; i++)
listeners[i].apply(this, args);
}
return true;
};
EventEmitter.prototype.addListener = function(type, listener) {
var m;
if (!isFunction(listener))
throw TypeError('listener must be a function');
if (!this._events)
this._events = {};
// To avoid recursion in the case that type === "newListener"! Before
// adding it to the listeners, first emit "newListener".
if (this._events.newListener)
this.emit('newListener', type,
isFunction(listener.listener) ?
listener.listener : listener);
if (!this._events[type])
// Optimize the case of one listener. Don't need the extra array object.
this._events[type] = listener;
else if (isObject(this._events[type]))
// If we've already got an array, just append.
this._events[type].push(listener);
else
// Adding the second element, need to change to array.
this._events[type] = [this._events[type], listener];
// Check for listener leak
if (isObject(this._events[type]) && !this._events[type].warned) {
if (!isUndefined(this._maxListeners)) {
m = this._maxListeners;
} else {
m = EventEmitter.defaultMaxListeners;
}
if (m && m > 0 && this._events[type].length > m) {
this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' +
'leak detected. %d listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.',
this._events[type].length);
if (typeof console.trace === 'function') {
// not supported in IE 10
console.trace();
}
}
}
return this;
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.once = function(type, listener) {
if (!isFunction(listener))
throw TypeError('listener must be a function');
var fired = false;
function g() {
this.removeListener(type, g);
if (!fired) {
fired = true;
listener.apply(this, arguments);
}
}
g.listener = listener;
this.on(type, g);
return this;
};
// emits a 'removeListener' event iff the listener was removed
EventEmitter.prototype.removeListener = function(type, listener) {
var list, position, length, i;
if (!isFunction(listener))
throw TypeError('listener must be a function');
if (!this._events || !this._events[type])
return this;
list = this._events[type];
length = list.length;
position = -1;
if (list === listener ||
(isFunction(list.listener) && list.listener === listener)) {
delete this._events[type];
if (this._events.removeListener)
this.emit('removeListener', type, listener);
} else if (isObject(list)) {
for (i = length; i-- > 0;) {
if (list[i] === listener ||
(list[i].listener && list[i].listener === listener)) {
position = i;
break;
}
}
if (position < 0)
return this;
if (list.length === 1) {
list.length = 0;
delete this._events[type];
} else {
list.splice(position, 1);
}
if (this._events.removeListener)
this.emit('removeListener', type, listener);
}
return this;
};
EventEmitter.prototype.removeAllListeners = function(type) {
var key, listeners;
if (!this._events)
return this;
// not listening for removeListener, no need to emit
if (!this._events.removeListener) {
if (arguments.length === 0)
this._events = {};
else if (this._events[type])
delete this._events[type];
return this;
}
// emit removeListener for all listeners on all events
if (arguments.length === 0) {
for (key in this._events) {
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = {};
return this;
}
listeners = this._events[type];
if (isFunction(listeners)) {
this.removeListener(type, listeners);
} else if (listeners) {
// LIFO order
while (listeners.length)
this.removeListener(type, listeners[listeners.length - 1]);
}
delete this._events[type];
return this;
};
EventEmitter.prototype.listeners = function(type) {
var ret;
if (!this._events || !this._events[type])
ret = [];
else if (isFunction(this._events[type]))
ret = [this._events[type]];
else
ret = this._events[type].slice();
return ret;
};
EventEmitter.prototype.listenerCount = function(type) {
if (this._events) {
var evlistener = this._events[type];
if (isFunction(evlistener))
return 1;
else if (evlistener)
return evlistener.length;
}
return 0;
};
EventEmitter.listenerCount = function(emitter, type) {
return emitter.listenerCount(type);
};
function isFunction(arg) {
return typeof arg === 'function';
}
function isNumber(arg) {
return typeof arg === 'number';
}
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
function isUndefined(arg) {
return arg === void 0;
}
/***/ }),
/* 130 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(129).EventEmitter;
/***/ }),
/* 131 */
/***/ (function(module, exports, __webpack_require__) {
/* eslint-disable node/no-deprecated-api */
var buffer = __webpack_require__(106)
var Buffer = buffer.Buffer
// alternative to using Object.keys for old browsers
function copyProps (src, dst) {
for (var key in src) {
dst[key] = src[key]
}
}
if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
module.exports = buffer
} else {
// Copy properties from require('buffer')
copyProps(buffer, exports)
exports.Buffer = SafeBuffer
}
function SafeBuffer (arg, encodingOrOffset, length) {
return Buffer(arg, encodingOrOffset, length)
}
// Copy static methods from Buffer
copyProps(Buffer, SafeBuffer)
SafeBuffer.from = function (arg, encodingOrOffset, length) {
if (typeof arg === 'number') {
throw new TypeError('Argument must not be a number')
}
return Buffer(arg, encodingOrOffset, length)
}
SafeBuffer.alloc = function (size, fill, encoding) {
if (typeof size !== 'number') {
throw new TypeError('Argument must be a number')
}
var buf = Buffer(size)
if (fill !== undefined) {
if (typeof encoding === 'string') {
buf.fill(fill, encoding)
} else {
buf.fill(fill)
}
} else {
buf.fill(0)
}
return buf
}
SafeBuffer.allocUnsafe = function (size) {
if (typeof size !== 'number') {
throw new TypeError('Argument must be a number')
}
return Buffer(size)
}
SafeBuffer.allocUnsafeSlow = function (size) {
if (typeof size !== 'number') {
throw new TypeError('Argument must be a number')
}
return buffer.SlowBuffer(size)
}
/***/ }),
/* 132 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(Buffer) {// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// NOTE: These type checking functions intentionally don't use `instanceof`
// because it is fragile and can be easily faked with `Object.create()`.
function isArray(arg) {
if (Array.isArray) {
return Array.isArray(arg);
}
return objectToString(arg) === '[object Array]';
}
exports.isArray = isArray;
function isBoolean(arg) {
return typeof arg === 'boolean';
}
exports.isBoolean = isBoolean;
function isNull(arg) {
return arg === null;
}
exports.isNull = isNull;
function isNullOrUndefined(arg) {
return arg == null;
}
exports.isNullOrUndefined = isNullOrUndefined;
function isNumber(arg) {
return typeof arg === 'number';
}
exports.isNumber = isNumber;
function isString(arg) {
return typeof arg === 'string';
}
exports.isString = isString;
function isSymbol(arg) {
return typeof arg === 'symbol';
}
exports.isSymbol = isSymbol;
function isUndefined(arg) {
return arg === void 0;
}
exports.isUndefined = isUndefined;
function isRegExp(re) {
return objectToString(re) === '[object RegExp]';
}
exports.isRegExp = isRegExp;
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
exports.isObject = isObject;
function isDate(d) {
return objectToString(d) === '[object Date]';
}
exports.isDate = isDate;
function isError(e) {
return (objectToString(e) === '[object Error]' || e instanceof Error);
}
exports.isError = isError;
function isFunction(arg) {
return typeof arg === 'function';
}
exports.isFunction = isFunction;
function isPrimitive(arg) {
return arg === null ||
typeof arg === 'boolean' ||
typeof arg === 'number' ||
typeof arg === 'string' ||
typeof arg === 'symbol' || // ES6 symbol
typeof arg === 'undefined';
}
exports.isPrimitive = isPrimitive;
exports.isBuffer = Buffer.isBuffer;
function objectToString(o) {
return Object.prototype.toString.call(o);
}
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(106).Buffer))
/***/ }),
/* 133 */
/***/ (function(module, exports) {
/* (ignored) */
/***/ }),
/* 134 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Buffer = __webpack_require__(131).Buffer;
var util = __webpack_require__(135);
function copyBuffer(src, target, offset) {
src.copy(target, offset);
}
module.exports = function () {
function BufferList() {
_classCallCheck(this, BufferList);
this.head = null;
this.tail = null;
this.length = 0;
}
BufferList.prototype.push = function push(v) {
var entry = { data: v, next: null };
if (this.length > 0) this.tail.next = entry;else this.head = entry;
this.tail = entry;
++this.length;
};
BufferList.prototype.unshift = function unshift(v) {
var entry = { data: v, next: this.head };
if (this.length === 0) this.tail = entry;
this.head = entry;
++this.length;
};
BufferList.prototype.shift = function shift() {
if (this.length === 0) return;
var ret = this.head.data;
if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;
--this.length;
return ret;
};
BufferList.prototype.clear = function clear() {
this.head = this.tail = null;
this.length = 0;
};
BufferList.prototype.join = function join(s) {
if (this.length === 0) return '';
var p = this.head;
var ret = '' + p.data;
while (p = p.next) {
ret += s + p.data;
}return ret;
};
BufferList.prototype.concat = function concat(n) {
if (this.length === 0) return Buffer.alloc(0);
if (this.length === 1) return this.head.data;
var ret = Buffer.allocUnsafe(n >>> 0);
var p = this.head;
var i = 0;
while (p) {
copyBuffer(p.data, ret, i);
i += p.data.length;
p = p.next;
}
return ret;
};
return BufferList;
}();
if (util && util.inspect && util.inspect.custom) {
module.exports.prototype[util.inspect.custom] = function () {
var obj = util.inspect({ length: this.length });
return this.constructor.name + ' ' + obj;
};
}
/***/ }),
/* 135 */
/***/ (function(module, exports) {
/* (ignored) */
/***/ }),
/* 136 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
/*<replacement>*/
var pna = __webpack_require__(128);
/*</replacement>*/
// undocumented cb() API, needed for core, not for public API
function destroy(err, cb) {
var _this = this;
var readableDestroyed = this._readableState && this._readableState.destroyed;
var writableDestroyed = this._writableState && this._writableState.destroyed;
if (readableDestroyed || writableDestroyed) {
if (cb) {
cb(err);
} else if (err && (!this._writableState || !this._writableState.errorEmitted)) {
pna.nextTick(emitErrorNT, this, err);
}
return this;
}
// we set destroyed to true before firing error callbacks in order
// to make it re-entrance safe in case destroy() is called within callbacks
if (this._readableState) {
this._readableState.destroyed = true;
}
// if this is a duplex stream mark the writable part as destroyed as well
if (this._writableState) {
this._writableState.destroyed = true;
}
this._destroy(err || null, function (err) {
if (!cb && err) {
pna.nextTick(emitErrorNT, _this, err);
if (_this._writableState) {
_this._writableState.errorEmitted = true;
}
} else if (cb) {
cb(err);
}
});
return this;
}
function undestroy() {
if (this._readableState) {
this._readableState.destroyed = false;
this._readableState.reading = false;
this._readableState.ended = false;
this._readableState.endEmitted = false;
}
if (this._writableState) {
this._writableState.destroyed = false;
this._writableState.ended = false;
this._writableState.ending = false;
this._writableState.finished = false;
this._writableState.errorEmitted = false;
}
}
function emitErrorNT(self, err) {
self.emit('error', err);
}
module.exports = {
destroy: destroy,
undestroy: undestroy
};
/***/ }),
/* 137 */
/***/ (function(module, exports, __webpack_require__) {
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// a duplex stream is just a stream that is both readable and writable.
// Since JS doesn't have multiple prototypal inheritance, this class
// prototypally inherits from Readable, and then parasitically from
// Writable.
'use strict';
/*<replacement>*/
var pna = __webpack_require__(128);
/*</replacement>*/
/*<replacement>*/
var objectKeys = Object.keys || function (obj) {
var keys = [];
for (var key in obj) {
keys.push(key);
}return keys;
};
/*</replacement>*/
module.exports = Duplex;
/*<replacement>*/
var util = __webpack_require__(132);
util.inherits = __webpack_require__(124);
/*</replacement>*/
var Readable = __webpack_require__(127);
var Writable = __webpack_require__(138);
util.inherits(Duplex, Readable);
{
// avoid scope creep, the keys array can then be collected
var keys = objectKeys(Writable.prototype);
for (var v = 0; v < keys.length; v++) {
var method = keys[v];
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
}
}
function Duplex(options) {
if (!(this instanceof Duplex)) return new Duplex(options);
Readable.call(this, options);
Writable.call(this, options);
if (options && options.readable === false) this.readable = false;
if (options && options.writable === false) this.writable = false;
this.allowHalfOpen = true;
if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;
this.once('end', onend);
}
Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', {
// making it explicit this property is not enumerable
// because otherwise some prototype manipulation in
// userland will fail
enumerable: false,
get: function () {
return this._writableState.highWaterMark;
}
});
// the no-half-open enforcer
function onend() {
// if we allow half-open state, or if the writable side ended,
// then we're ok.
if (this.allowHalfOpen || this._writableState.ended) return;
// no more data can be written.
// But allow more writes to happen in this tick.
pna.nextTick(onEndNT, this);
}
function onEndNT(self) {
self.end();
}
Object.defineProperty(Duplex.prototype, 'destroyed', {
get: function () {
if (this._readableState === undefined || this._writableState === undefined) {
return false;
}
return this._readableState.destroyed && this._writableState.destroyed;
},
set: function (value) {
// we ignore the value if the stream
// has not been initialized yet
if (this._readableState === undefined || this._writableState === undefined) {
return;
}
// backward compatibility, the user is explicitly
// managing destroyed
this._readableState.destroyed = value;
this._writableState.destroyed = value;
}
});
Duplex.prototype._destroy = function (err, cb) {
this.push(null);
this.end();
pna.nextTick(cb, err);
};
/***/ }),
/* 138 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(process, setImmediate, global) {// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// A bit simpler than readable streams.
// Implement an async ._write(chunk, encoding, cb), and it'll handle all
// the drain event emission and buffering.
'use strict';
/*<replacement>*/
var pna = __webpack_require__(128);
/*</replacement>*/
module.exports = Writable;
/* <replacement> */
function WriteReq(chunk, encoding, cb) {
this.chunk = chunk;
this.encoding = encoding;
this.callback = cb;
this.next = null;
}
// It seems a linked list but it is not
// there will be only 2 of these for each stream
function CorkedRequest(state) {
var _this = this;
this.next = null;
this.entry = null;
this.finish = function () {
onCorkedFinish(_this, state);
};
}
/* </replacement> */
/*<replacement>*/
var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : pna.nextTick;
/*</replacement>*/
/*<replacement>*/
var Duplex;
/*</replacement>*/
Writable.WritableState = WritableState;
/*<replacement>*/
var util = __webpack_require__(132);
util.inherits = __webpack_require__(124);
/*</replacement>*/
/*<replacement>*/
var internalUtil = {
deprecate: __webpack_require__(141)
};
/*</replacement>*/
/*<replacement>*/
var Stream = __webpack_require__(130);
/*</replacement>*/
/*<replacement>*/
var Buffer = __webpack_require__(131).Buffer;
var OurUint8Array = global.Uint8Array || function () {};
function _uint8ArrayToBuffer(chunk) {
return Buffer.from(chunk);
}
function _isUint8Array(obj) {
return Buffer.isBuffer(obj) || obj instanceof OurUint8Array;
}
/*</replacement>*/
var destroyImpl = __webpack_require__(136);
util.inherits(Writable, Stream);
function nop() {}
function WritableState(options, stream) {
Duplex = Duplex || __webpack_require__(137);
options = options || {};
// Duplex streams are both readable and writable, but share
// the same options object.
// However, some cases require setting options to different
// values for the readable and the writable sides of the duplex stream.
// These options can be provided separately as readableXXX and writableXXX.
var isDuplex = stream instanceof Duplex;
// object stream flag to indicate whether or not this stream
// contains buffers or objects.
this.objectMode = !!options.objectMode;
if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
// the point at which write() starts returning false
// Note: 0 is a valid value, means that we always return false if
// the entire buffer is not flushed immediately on write()
var hwm = options.highWaterMark;
var writableHwm = options.writableHighWaterMark;
var defaultHwm = this.objectMode ? 16 : 16 * 1024;
if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (writableHwm || writableHwm === 0)) this.highWaterMark = writableHwm;else this.highWaterMark = defaultHwm;
// cast to ints.
this.highWaterMark = Math.floor(this.highWaterMark);
// if _final has been called
this.finalCalled = false;
// drain event flag.
this.needDrain = false;
// at the start of calling end()
this.ending = false;
// when end() has been called, and returned
this.ended = false;
// when 'finish' is emitted
this.finished = false;
// has it been destroyed
this.destroyed = false;
// should we decode strings into buffers before passing to _write?
// this is here so that some node-core streams can optimize string
// handling at a lower level.
var noDecode = options.decodeStrings === false;
this.decodeStrings = !noDecode;
// Crypto is kind of old and crusty. Historically, its default string
// encoding is 'binary' so we have to make this configurable.
// Everything else in the universe uses 'utf8', though.
this.defaultEncoding = options.defaultEncoding || 'utf8';
// not an actual buffer we keep track of, but a measurement
// of how much we're waiting to get pushed to some underlying
// socket or file.
this.length = 0;
// a flag to see when we're in the middle of a write.
this.writing = false;
// when true all writes will be buffered until .uncork() call
this.corked = 0;
// a flag to be able to tell if the onwrite cb is called immediately,
// or on a later tick. We set this to true at first, because any
// actions that shouldn't happen until "later" should generally also
// not happen before the first write call.
this.sync = true;
// a flag to know if we're processing previously buffered items, which
// may call the _write() callback in the same tick, so that we don't
// end up in an overlapped onwrite situation.
this.bufferProcessing = false;
// the callback that's passed to _write(chunk,cb)
this.onwrite = function (er) {
onwrite(stream, er);
};
// the callback that the user supplies to write(chunk,encoding,cb)
this.writecb = null;
// the amount that is being written when _write is called.
this.writelen = 0;
this.bufferedRequest = null;
this.lastBufferedRequest = null;
// number of pending user-supplied write callbacks
// this must be 0 before 'finish' can be emitted
this.pendingcb = 0;
// emit prefinish if the only thing we're waiting for is _write cbs
// This is relevant for synchronous Transform streams
this.prefinished = false;
// True if the error was already emitted and should not be thrown again
this.errorEmitted = false;
// count buffered requests
this.bufferedRequestCount = 0;
// allocate the first CorkedRequest, there is always
// one allocated and free to use, and we maintain at most two
this.corkedRequestsFree = new CorkedRequest(this);
}
WritableState.prototype.getBuffer = function getBuffer() {
var current = this.bufferedRequest;
var out = [];
while (current) {
out.push(current);
current = current.next;
}
return out;
};
(function () {
try {
Object.defineProperty(WritableState.prototype, 'buffer', {
get: internalUtil.deprecate(function () {
return this.getBuffer();
}, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003')
});
} catch (_) {}
})();
// Test _writableState for inheritance to account for Duplex streams,
// whose prototype chain only points to Readable.
var realHasInstance;
if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {
realHasInstance = Function.prototype[Symbol.hasInstance];
Object.defineProperty(Writable, Symbol.hasInstance, {
value: function (object) {
if (realHasInstance.call(this, object)) return true;
if (this !== Writable) return false;
return object && object._writableState instanceof WritableState;
}
});
} else {
realHasInstance = function (object) {
return object instanceof this;
};
}
function Writable(options) {
Duplex = Duplex || __webpack_require__(137);
// Writable ctor is applied to Duplexes, too.
// `realHasInstance` is necessary because using plain `instanceof`
// would return false, as no `_writableState` property is attached.
// Trying to use the custom `instanceof` for Writable here will also break the
// Node.js LazyTransform implementation, which has a non-trivial getter for
// `_writableState` that would lead to infinite recursion.
if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) {
return new Writable(options);
}
this._writableState = new WritableState(options, this);
// legacy.
this.writable = true;
if (options) {
if (typeof options.write === 'function') this._write = options.write;
if (typeof options.writev === 'function') this._writev = options.writev;
if (typeof options.destroy === 'function') this._destroy = options.destroy;
if (typeof options.final === 'function') this._final = options.final;
}
Stream.call(this);
}
// Otherwise people can pipe Writable streams, which is just wrong.
Writable.prototype.pipe = function () {
this.emit('error', new Error('Cannot pipe, not readable'));
};
function writeAfterEnd(stream, cb) {
var er = new Error('write after end');
// TODO: defer error events consistently everywhere, not just the cb
stream.emit('error', er);
pna.nextTick(cb, er);
}
// Checks that a user-supplied chunk is valid, especially for the particular
// mode the stream is in. Currently this means that `null` is never accepted
// and undefined/non-string values are only allowed in object mode.
function validChunk(stream, state, chunk, cb) {
var valid = true;
var er = false;
if (chunk === null) {
er = new TypeError('May not write null values to stream');
} else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
er = new TypeError('Invalid non-string/buffer chunk');
}
if (er) {
stream.emit('error', er);
pna.nextTick(cb, er);
valid = false;
}
return valid;
}
Writable.prototype.write = function (chunk, encoding, cb) {
var state = this._writableState;
var ret = false;
var isBuf = !state.objectMode && _isUint8Array(chunk);
if (isBuf && !Buffer.isBuffer(chunk)) {
chunk = _uint8ArrayToBuffer(chunk);
}
if (typeof encoding === 'function') {
cb = encoding;
encoding = null;
}
if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
if (typeof cb !== 'function') cb = nop;
if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) {
state.pendingcb++;
ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
}
return ret;
};
Writable.prototype.cork = function () {
var state = this._writableState;
state.corked++;
};
Writable.prototype.uncork = function () {
var state = this._writableState;
if (state.corked) {
state.corked--;
if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
}
};
Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
// node::ParseEncoding() requires lower case.
if (typeof encoding === 'string') encoding = encoding.toLowerCase();
if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
this._writableState.defaultEncoding = encoding;
return this;
};
function decodeChunk(state, chunk, encoding) {
if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
chunk = Buffer.from(chunk, encoding);
}
return chunk;
}
Object.defineProperty(Writable.prototype, 'writableHighWaterMark', {
// making it explicit this property is not enumerable
// because otherwise some prototype manipulation in
// userland will fail
enumerable: false,
get: function () {
return this._writableState.highWaterMark;
}
});
// if we're already writing something, then just put this
// in the queue, and wait our turn. Otherwise, call _write
// If we return false, then we need a drain event, so set that flag.
function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {
if (!isBuf) {
var newChunk = decodeChunk(state, chunk, encoding);
if (chunk !== newChunk) {
isBuf = true;
encoding = 'buffer';
chunk = newChunk;
}
}
var len = state.objectMode ? 1 : chunk.length;
state.length += len;
var ret = state.length < state.highWaterMark;
// we must ensure that previous needDrain will not be reset to false.
if (!ret) state.needDrain = true;
if (state.writing || state.corked) {
var last = state.lastBufferedRequest;
state.lastBufferedRequest = {
chunk: chunk,
encoding: encoding,
isBuf: isBuf,
callback: cb,
next: null
};
if (last) {
last.next = state.lastBufferedRequest;
} else {
state.bufferedRequest = state.lastBufferedRequest;
}
state.bufferedRequestCount += 1;
} else {
doWrite(stream, state, false, len, chunk, encoding, cb);
}
return ret;
}
function doWrite(stream, state, writev, len, chunk, encoding, cb) {
state.writelen = len;
state.writecb = cb;
state.writing = true;
state.sync = true;
if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
state.sync = false;
}
function onwriteError(stream, state, sync, er, cb) {
--state.pendingcb;
if (sync) {
// defer the callback if we are being called synchronously
// to avoid piling up things on the stack
pna.nextTick(cb, er);
// this can emit finish, and it will always happen
// after error
pna.nextTick(finishMaybe, stream, state);
stream._writableState.errorEmitted = true;
stream.emit('error', er);
} else {
// the caller expect this to happen before if
// it is async
cb(er);
stream._writableState.errorEmitted = true;
stream.emit('error', er);
// this can emit finish, but finish must
// always follow error
finishMaybe(stream, state);
}
}
function onwriteStateUpdate(state) {
state.writing = false;
state.writecb = null;
state.length -= state.writelen;
state.writelen = 0;
}
function onwrite(stream, er) {
var state = stream._writableState;
var sync = state.sync;
var cb = state.writecb;
onwriteStateUpdate(state);
if (er) onwriteError(stream, state, sync, er, cb);else {
// Check if we're actually ready to finish, but don't emit yet
var finished = needFinish(state);
if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
clearBuffer(stream, state);
}
if (sync) {
/*<replacement>*/
asyncWrite(afterWrite, stream, state, finished, cb);
/*</replacement>*/
} else {
afterWrite(stream, state, finished, cb);
}
}
}
function afterWrite(stream, state, finished, cb) {
if (!finished) onwriteDrain(stream, state);
state.pendingcb--;
cb();
finishMaybe(stream, state);
}
// Must force callback to be called on nextTick, so that we don't
// emit 'drain' before the write() consumer gets the 'false' return
// value, and has a chance to attach a 'drain' listener.
function onwriteDrain(stream, state) {
if (state.length === 0 && state.needDrain) {
state.needDrain = false;
stream.emit('drain');
}
}
// if there's something in the buffer waiting, then process it
function clearBuffer(stream, state) {
state.bufferProcessing = true;
var entry = state.bufferedRequest;
if (stream._writev && entry && entry.next) {
// Fast case, write everything using _writev()
var l = state.bufferedRequestCount;
var buffer = new Array(l);
var holder = state.corkedRequestsFree;
holder.entry = entry;
var count = 0;
var allBuffers = true;
while (entry) {
buffer[count] = entry;
if (!entry.isBuf) allBuffers = false;
entry = entry.next;
count += 1;
}
buffer.allBuffers = allBuffers;
doWrite(stream, state, true, state.length, buffer, '', holder.finish);
// doWrite is almost always async, defer these to save a bit of time
// as the hot path ends with doWrite
state.pendingcb++;
state.lastBufferedRequest = null;
if (holder.next) {
state.corkedRequestsFree = holder.next;
holder.next = null;
} else {
state.corkedRequestsFree = new CorkedRequest(state);
}
state.bufferedRequestCount = 0;
} else {
// Slow case, write chunks one-by-one
while (entry) {
var chunk = entry.chunk;
var encoding = entry.encoding;
var cb = entry.callback;
var len = state.objectMode ? 1 : chunk.length;
doWrite(stream, state, false, len, chunk, encoding, cb);
entry = entry.next;
state.bufferedRequestCount--;
// if we didn't call the onwrite immediately, then
// it means that we need to wait until it does.
// also, that means that the chunk and cb are currently
// being processed, so move the buffer counter past them.
if (state.writing) {
break;
}
}
if (entry === null) state.lastBufferedRequest = null;
}
state.bufferedRequest = entry;
state.bufferProcessing = false;
}
Writable.prototype._write = function (chunk, encoding, cb) {
cb(new Error('_write() is not implemented'));
};
Writable.prototype._writev = null;
Writable.prototype.end = function (chunk, encoding, cb) {
var state = this._writableState;
if (typeof chunk === 'function') {
cb = chunk;
chunk = null;
encoding = null;
} else if (typeof encoding === 'function') {
cb = encoding;
encoding = null;
}
if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
// .end() fully uncorks
if (state.corked) {
state.corked = 1;
this.uncork();
}
// ignore unnecessary end() calls.
if (!state.ending && !state.finished) endWritable(this, state, cb);
};
function needFinish(state) {
return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
}
function callFinal(stream, state) {
stream._final(function (err) {
state.pendingcb--;
if (err) {
stream.emit('error', err);
}
state.prefinished = true;
stream.emit('prefinish');
finishMaybe(stream, state);
});
}
function prefinish(stream, state) {
if (!state.prefinished && !state.finalCalled) {
if (typeof stream._final === 'function') {
state.pendingcb++;
state.finalCalled = true;
pna.nextTick(callFinal, stream, state);
} else {
state.prefinished = true;
stream.emit('prefinish');
}
}
}
function finishMaybe(stream, state) {
var need = needFinish(state);
if (need) {
prefinish(stream, state);
if (state.pendingcb === 0) {
state.finished = true;
stream.emit('finish');
}
}
return need;
}
function endWritable(stream, state, cb) {
state.ending = true;
finishMaybe(stream, state);
if (cb) {
if (state.finished) pna.nextTick(cb);else stream.once('finish', cb);
}
state.ended = true;
stream.writable = false;
}
function onCorkedFinish(corkReq, state, err) {
var entry = corkReq.entry;
corkReq.entry = null;
while (entry) {
var cb = entry.callback;
state.pendingcb--;
cb(err);
entry = entry.next;
}
if (state.corkedRequestsFree) {
state.corkedRequestsFree.next = corkReq;
} else {
state.corkedRequestsFree = corkReq;
}
}
Object.defineProperty(Writable.prototype, 'destroyed', {
get: function () {
if (this._writableState === undefined) {
return false;
}
return this._writableState.destroyed;
},
set: function (value) {
// we ignore the value if the stream
// has not been initialized yet
if (!this._writableState) {
return;
}
// backward compatibility, the user is explicitly
// managing destroyed
this._writableState.destroyed = value;
}
});
Writable.prototype.destroy = destroyImpl.destroy;
Writable.prototype._undestroy = destroyImpl.undestroy;
Writable.prototype._destroy = function (err, cb) {
this.end();
cb(err);
};
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(110), __webpack_require__(139).setImmediate, (function() { return this; }())))
/***/ }),
/* 139 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {var scope = (typeof global !== "undefined" && global) ||
(typeof self !== "undefined" && self) ||
window;
var apply = Function.prototype.apply;
// DOM APIs, for completeness
exports.setTimeout = function() {
return new Timeout(apply.call(setTimeout, scope, arguments), clearTimeout);
};
exports.setInterval = function() {
return new Timeout(apply.call(setInterval, scope, arguments), clearInterval);
};
exports.clearTimeout =
exports.clearInterval = function(timeout) {
if (timeout) {
timeout.close();
}
};
function Timeout(id, clearFn) {
this._id = id;
this._clearFn = clearFn;
}
Timeout.prototype.unref = Timeout.prototype.ref = function() {};
Timeout.prototype.close = function() {
this._clearFn.call(scope, this._id);
};
// Does not start the time, just sets up the members needed.
exports.enroll = function(item, msecs) {
clearTimeout(item._idleTimeoutId);
item._idleTimeout = msecs;
};
exports.unenroll = function(item) {
clearTimeout(item._idleTimeoutId);
item._idleTimeout = -1;
};
exports._unrefActive = exports.active = function(item) {
clearTimeout(item._idleTimeoutId);
var msecs = item._idleTimeout;
if (msecs >= 0) {
item._idleTimeoutId = setTimeout(function onTimeout() {
if (item._onTimeout)
item._onTimeout();
}, msecs);
}
};
// setimmediate attaches itself to the global object
__webpack_require__(140);
// On some exotic environments, it's not clear which object `setimmediate` was
// able to install onto. Search each possibility in the same order as the
// `setimmediate` library.
exports.setImmediate = (typeof self !== "undefined" && self.setImmediate) ||
(typeof global !== "undefined" && global.setImmediate) ||
(this && this.setImmediate);
exports.clearImmediate = (typeof self !== "undefined" && self.clearImmediate) ||
(typeof global !== "undefined" && global.clearImmediate) ||
(this && this.clearImmediate);
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ }),
/* 140 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) {
"use strict";
if (global.setImmediate) {
return;
}
var nextHandle = 1; // Spec says greater than zero
var tasksByHandle = {};
var currentlyRunningATask = false;
var doc = global.document;
var registerImmediate;
function setImmediate(callback) {
// Callback can either be a function or a string
if (typeof callback !== "function") {
callback = new Function("" + callback);
}
// Copy function arguments
var args = new Array(arguments.length - 1);
for (var i = 0; i < args.length; i++) {
args[i] = arguments[i + 1];
}
// Store and register the task
var task = { callback: callback, args: args };
tasksByHandle[nextHandle] = task;
registerImmediate(nextHandle);
return nextHandle++;
}
function clearImmediate(handle) {
delete tasksByHandle[handle];
}
function run(task) {
var callback = task.callback;
var args = task.args;
switch (args.length) {
case 0:
callback();
break;
case 1:
callback(args[0]);
break;
case 2:
callback(args[0], args[1]);
break;
case 3:
callback(args[0], args[1], args[2]);
break;
default:
callback.apply(undefined, args);
break;
}
}
function runIfPresent(handle) {
// From the spec: "Wait until any invocations of this algorithm started before this one have completed."
// So if we're currently running a task, we'll need to delay this invocation.
if (currentlyRunningATask) {
// Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
// "too much recursion" error.
setTimeout(runIfPresent, 0, handle);
} else {
var task = tasksByHandle[handle];
if (task) {
currentlyRunningATask = true;
try {
run(task);
} finally {
clearImmediate(handle);
currentlyRunningATask = false;
}
}
}
}
function installNextTickImplementation() {
registerImmediate = function(handle) {
process.nextTick(function () { runIfPresent(handle); });
};
}
function canUsePostMessage() {
// The test against `importScripts` prevents this implementation from being installed inside a web worker,
// where `global.postMessage` means something completely different and can't be used for this purpose.
if (global.postMessage && !global.importScripts) {
var postMessageIsAsynchronous = true;
var oldOnMessage = global.onmessage;
global.onmessage = function() {
postMessageIsAsynchronous = false;
};
global.postMessage("", "*");
global.onmessage = oldOnMessage;
return postMessageIsAsynchronous;
}
}
function installPostMessageImplementation() {
// Installs an event handler on `global` for the `message` event: see
// * https://developer.mozilla.org/en/DOM/window.postMessage
// * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
var messagePrefix = "setImmediate$" + Math.random() + "$";
var onGlobalMessage = function(event) {
if (event.source === global &&
typeof event.data === "string" &&
event.data.indexOf(messagePrefix) === 0) {
runIfPresent(+event.data.slice(messagePrefix.length));
}
};
if (global.addEventListener) {
global.addEventListener("message", onGlobalMessage, false);
} else {
global.attachEvent("onmessage", onGlobalMessage);
}
registerImmediate = function(handle) {
global.postMessage(messagePrefix + handle, "*");
};
}
function installMessageChannelImplementation() {
var channel = new MessageChannel();
channel.port1.onmessage = function(event) {
var handle = event.data;
runIfPresent(handle);
};
registerImmediate = function(handle) {
channel.port2.postMessage(handle);
};
}
function installReadyStateChangeImplementation() {
var html = doc.documentElement;
registerImmediate = function(handle) {
// Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
// into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
var script = doc.createElement("script");
script.onreadystatechange = function () {
runIfPresent(handle);
script.onreadystatechange = null;
html.removeChild(script);
script = null;
};
html.appendChild(script);
};
}
function installSetTimeoutImplementation() {
registerImmediate = function(handle) {
setTimeout(runIfPresent, 0, handle);
};
}
// If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);
attachTo = attachTo && attachTo.setTimeout ? attachTo : global;
// Don't get fooled by e.g. browserify environments.
if ({}.toString.call(global.process) === "[object process]") {
// For Node.js before 0.9
installNextTickImplementation();
} else if (canUsePostMessage()) {
// For non-IE10 modern browsers
installPostMessageImplementation();
} else if (global.MessageChannel) {
// For web workers, where supported
installMessageChannelImplementation();
} else if (doc && "onreadystatechange" in doc.createElement("script")) {
// For IE 6–8
installReadyStateChangeImplementation();
} else {
// For older browsers
installSetTimeoutImplementation();
}
attachTo.setImmediate = setImmediate;
attachTo.clearImmediate = clearImmediate;
}(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self));
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(110)))
/***/ }),
/* 141 */
/***/ (function(module, exports) {
/* WEBPACK VAR INJECTION */(function(global) {
/**
* Module exports.
*/
module.exports = deprecate;
/**
* Mark that a method should not be used.
* Returns a modified function which warns once by default.
*
* If `localStorage.noDeprecation = true` is set, then it is a no-op.
*
* If `localStorage.throwDeprecation = true` is set, then deprecated functions
* will throw an Error when invoked.
*
* If `localStorage.traceDeprecation = true` is set, then deprecated functions
* will invoke `console.trace()` instead of `console.error()`.
*
* @param {Function} fn - the function to deprecate
* @param {String} msg - the string to print to the console when `fn` is invoked
* @returns {Function} a new "deprecated" version of `fn`
* @api public
*/
function deprecate (fn, msg) {
if (config('noDeprecation')) {
return fn;
}
var warned = false;
function deprecated() {
if (!warned) {
if (config('throwDeprecation')) {
throw new Error(msg);
} else if (config('traceDeprecation')) {
console.trace(msg);
} else {
console.warn(msg);
}
warned = true;
}
return fn.apply(this, arguments);
}
return deprecated;
}
/**
* Checks `localStorage` for boolean values for the given `name`.
*
* @param {String} name
* @returns {Boolean}
* @api private
*/
function config (name) {
// accessing global.localStorage can trigger a DOMException in sandboxed iframes
try {
if (!global.localStorage) return false;
} catch (_) {
return false;
}
var val = global.localStorage[name];
if (null == val) return false;
return String(val).toLowerCase() === 'true';
}
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
/***/ }),
/* 142 */
/***/ (function(module, exports, __webpack_require__) {
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
/*<replacement>*/
var Buffer = __webpack_require__(131).Buffer;
/*</replacement>*/
var isEncoding = Buffer.isEncoding || function (encoding) {
encoding = '' + encoding;
switch (encoding && encoding.toLowerCase()) {
case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw':
return true;
default:
return false;
}
};
function _normalizeEncoding(enc) {
if (!enc) return 'utf8';
var retried;
while (true) {
switch (enc) {
case 'utf8':
case 'utf-8':
return 'utf8';
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return 'utf16le';
case 'latin1':
case 'binary':
return 'latin1';
case 'base64':
case 'ascii':
case 'hex':
return enc;
default:
if (retried) return; // undefined
enc = ('' + enc).toLowerCase();
retried = true;
}
}
};
// Do not cache `Buffer.isEncoding` when checking encoding names as some
// modules monkey-patch it to support additional encodings
function normalizeEncoding(enc) {
var nenc = _normalizeEncoding(enc);
if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc);
return nenc || enc;
}
// StringDecoder provides an interface for efficiently splitting a series of
// buffers into a series of JS strings without breaking apart multi-byte
// characters.
exports.StringDecoder = StringDecoder;
function StringDecoder(encoding) {
this.encoding = normalizeEncoding(encoding);
var nb;
switch (this.encoding) {
case 'utf16le':
this.text = utf16Text;
this.end = utf16End;
nb = 4;
break;
case 'utf8':
this.fillLast = utf8FillLast;
nb = 4;
break;
case 'base64':
this.text = base64Text;
this.end = base64End;
nb = 3;
break;
default:
this.write = simpleWrite;
this.end = simpleEnd;
return;
}
this.lastNeed = 0;
this.lastTotal = 0;
this.lastChar = Buffer.allocUnsafe(nb);
}
StringDecoder.prototype.write = function (buf) {
if (buf.length === 0) return '';
var r;
var i;
if (this.lastNeed) {
r = this.fillLast(buf);
if (r === undefined) return '';
i = this.lastNeed;
this.lastNeed = 0;
} else {
i = 0;
}
if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i);
return r || '';
};
StringDecoder.prototype.end = utf8End;
// Returns only complete characters in a Buffer
StringDecoder.prototype.text = utf8Text;
// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer
StringDecoder.prototype.fillLast = function (buf) {
if (this.lastNeed <= buf.length) {
buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed);
return this.lastChar.toString(this.encoding, 0, this.lastTotal);
}
buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length);
this.lastNeed -= buf.length;
};
// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a
// continuation byte. If an invalid byte is detected, -2 is returned.
function utf8CheckByte(byte) {
if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4;
return byte >> 6 === 0x02 ? -1 : -2;
}
// Checks at most 3 bytes at the end of a Buffer in order to detect an
// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4)
// needed to complete the UTF-8 character (if applicable) are returned.
function utf8CheckIncomplete(self, buf, i) {
var j = buf.length - 1;
if (j < i) return 0;
var nb = utf8CheckByte(buf[j]);
if (nb >= 0) {
if (nb > 0) self.lastNeed = nb - 1;
return nb;
}
if (--j < i || nb === -2) return 0;
nb = utf8CheckByte(buf[j]);
if (nb >= 0) {
if (nb > 0) self.lastNeed = nb - 2;
return nb;
}
if (--j < i || nb === -2) return 0;
nb = utf8CheckByte(buf[j]);
if (nb >= 0) {
if (nb > 0) {
if (nb === 2) nb = 0;else self.lastNeed = nb - 3;
}
return nb;
}
return 0;
}
// Validates as many continuation bytes for a multi-byte UTF-8 character as
// needed or are available. If we see a non-continuation byte where we expect
// one, we "replace" the validated continuation bytes we've seen so far with
// a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding
// behavior. The continuation byte check is included three times in the case
// where all of the continuation bytes for a character exist in the same buffer.
// It is also done this way as a slight performance increase instead of using a
// loop.
function utf8CheckExtraBytes(self, buf, p) {
if ((buf[0] & 0xC0) !== 0x80) {
self.lastNeed = 0;
return '\ufffd';
}
if (self.lastNeed > 1 && buf.length > 1) {
if ((buf[1] & 0xC0) !== 0x80) {
self.lastNeed = 1;
return '\ufffd';
}
if (self.lastNeed > 2 && buf.length > 2) {
if ((buf[2] & 0xC0) !== 0x80) {
self.lastNeed = 2;
return '\ufffd';
}
}
}
}
// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer.
function utf8FillLast(buf) {
var p = this.lastTotal - this.lastNeed;
var r = utf8CheckExtraBytes(this, buf, p);
if (r !== undefined) return r;
if (this.lastNeed <= buf.length) {
buf.copy(this.lastChar, p, 0, this.lastNeed);
return this.lastChar.toString(this.encoding, 0, this.lastTotal);
}
buf.copy(this.lastChar, p, 0, buf.length);
this.lastNeed -= buf.length;
}
// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a
// partial character, the character's bytes are buffered until the required
// number of bytes are available.
function utf8Text(buf, i) {
var total = utf8CheckIncomplete(this, buf, i);
if (!this.lastNeed) return buf.toString('utf8', i);
this.lastTotal = total;
var end = buf.length - (total - this.lastNeed);
buf.copy(this.lastChar, 0, end);
return buf.toString('utf8', i, end);
}
// For UTF-8, a replacement character is added when ending on a partial
// character.
function utf8End(buf) {
var r = buf && buf.length ? this.write(buf) : '';
if (this.lastNeed) return r + '\ufffd';
return r;
}
// UTF-16LE typically needs two bytes per character, but even if we have an even
// number of bytes available, we need to check if we end on a leading/high
// surrogate. In that case, we need to wait for the next two bytes in order to
// decode the last character properly.
function utf16Text(buf, i) {
if ((buf.length - i) % 2 === 0) {
var r = buf.toString('utf16le', i);
if (r) {
var c = r.charCodeAt(r.length - 1);
if (c >= 0xD800 && c <= 0xDBFF) {
this.lastNeed = 2;
this.lastTotal = 4;
this.lastChar[0] = buf[buf.length - 2];
this.lastChar[1] = buf[buf.length - 1];
return r.slice(0, -1);
}
}
return r;
}
this.lastNeed = 1;
this.lastTotal = 2;
this.lastChar[0] = buf[buf.length - 1];
return buf.toString('utf16le', i, buf.length - 1);
}
// For UTF-16LE we do not explicitly append special replacement characters if we
// end on a partial character, we simply let v8 handle that.
function utf16End(buf) {
var r = buf && buf.length ? this.write(buf) : '';
if (this.lastNeed) {
var end = this.lastTotal - this.lastNeed;
return r + this.lastChar.toString('utf16le', 0, end);
}
return r;
}
function base64Text(buf, i) {
var n = (buf.length - i) % 3;
if (n === 0) return buf.toString('base64', i);
this.lastNeed = 3 - n;
this.lastTotal = 3;
if (n === 1) {
this.lastChar[0] = buf[buf.length - 1];
} else {
this.lastChar[0] = buf[buf.length - 2];
this.lastChar[1] = buf[buf.length - 1];
}
return buf.toString('base64', i, buf.length - n);
}
function base64End(buf) {
var r = buf && buf.length ? this.write(buf) : '';
if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed);
return r;
}
// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex)
function simpleWrite(buf) {
return buf.toString(this.encoding);
}
function simpleEnd(buf) {
return buf && buf.length ? this.write(buf) : '';
}
/***/ }),
/* 143 */
/***/ (function(module, exports, __webpack_require__) {
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// a transform stream is a readable/writable stream where you do
// something with the data. Sometimes it's called a "filter",
// but that's not a great name for it, since that implies a thing where
// some bits pass through, and others are simply ignored. (That would
// be a valid example of a transform, of course.)
//
// While the output is causally related to the input, it's not a
// necessarily symmetric or synchronous transformation. For example,
// a zlib stream might take multiple plain-text writes(), and then
// emit a single compressed chunk some time in the future.
//
// Here's how this works:
//
// The Transform stream has all the aspects of the readable and writable
// stream classes. When you write(chunk), that calls _write(chunk,cb)
// internally, and returns false if there's a lot of pending writes
// buffered up. When you call read(), that calls _read(n) until
// there's enough pending readable data buffered up.
//
// In a transform stream, the written data is placed in a buffer. When
// _read(n) is called, it transforms the queued up data, calling the
// buffered _write cb's as it consumes chunks. If consuming a single
// written chunk would result in multiple output chunks, then the first
// outputted bit calls the readcb, and subsequent chunks just go into
// the read buffer, and will cause it to emit 'readable' if necessary.
//
// This way, back-pressure is actually determined by the reading side,
// since _read has to be called to start processing a new chunk. However,
// a pathological inflate type of transform can cause excessive buffering
// here. For example, imagine a stream where every byte of input is
// interpreted as an integer from 0-255, and then results in that many
// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in
// 1kb of data being output. In this case, you could write a very small
// amount of input, and end up with a very large amount of output. In
// such a pathological inflating mechanism, there'd be no way to tell
// the system to stop doing the transform. A single 4MB write could
// cause the system to run out of memory.
//
// However, even in such a pathological case, only a single written chunk
// would be consumed, and then the rest would wait (un-transformed) until
// the results of the previous transformed chunk were consumed.
'use strict';
module.exports = Transform;
var Duplex = __webpack_require__(137);
/*<replacement>*/
var util = __webpack_require__(132);
util.inherits = __webpack_require__(124);
/*</replacement>*/
util.inherits(Transform, Duplex);
function afterTransform(er, data) {
var ts = this._transformState;
ts.transforming = false;
var cb = ts.writecb;
if (!cb) {
return this.emit('error', new Error('write callback called multiple times'));
}
ts.writechunk = null;
ts.writecb = null;
if (data != null) // single equals check for both `null` and `undefined`
this.push(data);
cb(er);
var rs = this._readableState;
rs.reading = false;
if (rs.needReadable || rs.length < rs.highWaterMark) {
this._read(rs.highWaterMark);
}
}
function Transform(options) {
if (!(this instanceof Transform)) return new Transform(options);
Duplex.call(this, options);
this._transformState = {
afterTransform: afterTransform.bind(this),
needTransform: false,
transforming: false,
writecb: null,
writechunk: null,
writeencoding: null
};
// start out asking for a readable event once data is transformed.
this._readableState.needReadable = true;
// we have implemented the _read method, and done the other things
// that Readable wants before the first _read call, so unset the
// sync guard flag.
this._readableState.sync = false;
if (options) {
if (typeof options.transform === 'function') this._transform = options.transform;
if (typeof options.flush === 'function') this._flush = options.flush;
}
// When the writable side finishes, then flush out anything remaining.
this.on('prefinish', prefinish);
}
function prefinish() {
var _this = this;
if (typeof this._flush === 'function') {
this._flush(function (er, data) {
done(_this, er, data);
});
} else {
done(this, null, null);
}
}
Transform.prototype.push = function (chunk, encoding) {
this._transformState.needTransform = false;
return Duplex.prototype.push.call(this, chunk, encoding);
};
// This is the part where you do stuff!
// override this function in implementation classes.
// 'chunk' is an input chunk.
//
// Call `push(newChunk)` to pass along transformed output
// to the readable side. You may call 'push' zero or more times.
//
// Call `cb(err)` when you are done with this chunk. If you pass
// an error, then that'll put the hurt on the whole operation. If you
// never call cb(), then you'll never get another chunk.
Transform.prototype._transform = function (chunk, encoding, cb) {
throw new Error('_transform() is not implemented');
};
Transform.prototype._write = function (chunk, encoding, cb) {
var ts = this._transformState;
ts.writecb = cb;
ts.writechunk = chunk;
ts.writeencoding = encoding;
if (!ts.transforming) {
var rs = this._readableState;
if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
}
};
// Doesn't matter what the args are here.
// _transform does all the work.
// That we got here means that the readable side wants more data.
Transform.prototype._read = function (n) {
var ts = this._transformState;
if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
ts.transforming = true;
this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
} else {
// mark that we need a transform, so that any data that comes in
// will get processed, now that we've asked for it.
ts.needTransform = true;
}
};
Transform.prototype._destroy = function (err, cb) {
var _this2 = this;
Duplex.prototype._destroy.call(this, err, function (err2) {
cb(err2);
_this2.emit('close');
});
};
function done(stream, er, data) {
if (er) return stream.emit('error', er);
if (data != null) // single equals check for both `null` and `undefined`
stream.push(data);
// if there's nothing in the write buffer, then that means
// that nothing more will ever be provided
if (stream._writableState.length) throw new Error('Calling transform done when ws.length != 0');
if (stream._transformState.transforming) throw new Error('Calling transform done when still transforming');
return stream.push(null);
}
/***/ }),
/* 144 */
/***/ (function(module, exports, __webpack_require__) {
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// a passthrough stream.
// basically just the most minimal sort of Transform stream.
// Every written chunk gets output as-is.
'use strict';
module.exports = PassThrough;
var Transform = __webpack_require__(143);
/*<replacement>*/
var util = __webpack_require__(132);
util.inherits = __webpack_require__(124);
/*</replacement>*/
util.inherits(PassThrough, Transform);
function PassThrough(options) {
if (!(this instanceof PassThrough)) return new PassThrough(options);
Transform.call(this, options);
}
PassThrough.prototype._transform = function (chunk, encoding, cb) {
cb(null, chunk);
};
/***/ }),
/* 145 */
/***/ (function(module, exports, __webpack_require__) {
var Buffer = __webpack_require__(106).Buffer
module.exports = function (buf) {
// If the buffer is backed by a Uint8Array, a faster version will work
if (buf instanceof Uint8Array) {
// If the buffer isn't a subarray, return the underlying ArrayBuffer
if (buf.byteOffset === 0 && buf.byteLength === buf.buffer.byteLength) {
return buf.buffer
} else if (typeof buf.buffer.slice === 'function') {
// Otherwise we need to get a proper copy
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength)
}
}
if (Buffer.isBuffer(buf)) {
// This is the slow version that will work with any Buffer
// implementation (even in old browsers)
var arrayCopy = new Uint8Array(buf.length)
var len = buf.length
for (var i = 0; i < len; i++) {
arrayCopy[i] = buf[i]
}
return arrayCopy.buffer
} else {
throw new Error('Argument must be a Buffer')
}
}
/***/ }),
/* 146 */
/***/ (function(module, exports) {
module.exports = extend
var hasOwnProperty = Object.prototype.hasOwnProperty;
function extend() {
var target = {}
for (var i = 0; i < arguments.length; i++) {
var source = arguments[i]
for (var key in source) {
if (hasOwnProperty.call(source, key)) {
target[key] = source[key]
}
}
}
return target
}
/***/ }),
/* 147 */
/***/ (function(module, exports) {
module.exports = {
"100": "Continue",
"101": "Switching Protocols",
"102": "Processing",
"200": "OK",
"201": "Created",
"202": "Accepted",
"203": "Non-Authoritative Information",
"204": "No Content",
"205": "Reset Content",
"206": "Partial Content",
"207": "Multi-Status",
"208": "Already Reported",
"226": "IM Used",
"300": "Multiple Choices",
"301": "Moved Permanently",
"302": "Found",
"303": "See Other",
"304": "Not Modified",
"305": "Use Proxy",
"307": "Temporary Redirect",
"308": "Permanent Redirect",
"400": "Bad Request",
"401": "Unauthorized",
"402": "Payment Required",
"403": "Forbidden",
"404": "Not Found",
"405": "Method Not Allowed",
"406": "Not Acceptable",
"407": "Proxy Authentication Required",
"408": "Request Timeout",
"409": "Conflict",
"410": "Gone",
"411": "Length Required",
"412": "Precondition Failed",
"413": "Payload Too Large",
"414": "URI Too Long",
"415": "Unsupported Media Type",
"416": "Range Not Satisfiable",
"417": "Expectation Failed",
"418": "I'm a teapot",
"421": "Misdirected Request",
"422": "Unprocessable Entity",
"423": "Locked",
"424": "Failed Dependency",
"425": "Unordered Collection",
"426": "Upgrade Required",
"428": "Precondition Required",
"429": "Too Many Requests",
"431": "Request Header Fields Too Large",
"451": "Unavailable For Legal Reasons",
"500": "Internal Server Error",
"501": "Not Implemented",
"502": "Bad Gateway",
"503": "Service Unavailable",
"504": "Gateway Timeout",
"505": "HTTP Version Not Supported",
"506": "Variant Also Negotiates",
"507": "Insufficient Storage",
"508": "Loop Detected",
"509": "Bandwidth Limit Exceeded",
"510": "Not Extended",
"511": "Network Authentication Required"
}
/***/ }),
/* 148 */
/***/ (function(module, exports, __webpack_require__) {
var http = __webpack_require__(121);
var https = module.exports;
for (var key in http) {
if (http.hasOwnProperty(key)) https[key] = http[key];
};
https.request = function (params, cb) {
if (!params) params = {};
params.scheme = 'https';
params.protocol = 'https:';
return http.request.call(this, params, cb);
}
/***/ }),
/* 149 */
/***/ (function(module, exports) {
/* (ignored) */
/***/ }),
/* 150 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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 _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _component = __webpack_require__(151);
var _component2 = _interopRequireDefault(_component);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Image loader
*/
var componentNames = _consts2.default.componentNames,
rejectMessages = _consts2.default.rejectMessages;
var imageOption = {
padding: 0,
crossOrigin: 'Anonymous'
};
/**
* ImageLoader components
* @extends {Component}
* @class ImageLoader
* @param {Graphics} graphics - Graphics instance
* @ignore
*/
var ImageLoader = function (_Component) {
_inherits(ImageLoader, _Component);
function ImageLoader(graphics) {
_classCallCheck(this, ImageLoader);
return _possibleConstructorReturn(this, (ImageLoader.__proto__ || Object.getPrototypeOf(ImageLoader)).call(this, componentNames.IMAGE_LOADER, graphics));
}
/**
* Load image from url
* @param {?string} imageName - File name
* @param {?(fabric.Image|string)} img - fabric.Image instance or URL of an image
* @returns {jQuery.Deferred} deferred
*/
_createClass(ImageLoader, [{
key: 'load',
value: function load(imageName, img) {
var _this2 = this;
var promise = void 0;
if (!imageName && !img) {
// Back to the initial state, not error.
var canvas = this.getCanvas();
canvas.backgroundImage = null;
canvas.renderAll();
promise = new _promise2.default(function (resolve) {
_this2.setCanvasImage('', null);
resolve();
});
} else {
promise = this._setBackgroundImage(img).then(function (oImage) {
_this2.setCanvasImage(imageName, oImage);
_this2.adjustCanvasDimension();
return oImage;
});
}
return promise;
}
/**
* Set background image
* @param {?(fabric.Image|String)} img fabric.Image instance or URL of an image to set background to
* @returns {$.Deferred} deferred
* @private
*/
}, {
key: '_setBackgroundImage',
value: function _setBackgroundImage(img) {
var _this3 = this;
if (!img) {
return _promise2.default.reject(rejectMessages.loadImage);
}
return new _promise2.default(function (resolve, reject) {
var canvas = _this3.getCanvas();
canvas.setBackgroundImage(img, function () {
var oImage = canvas.backgroundImage;
if (oImage.getElement()) {
resolve(oImage);
} else {
reject(rejectMessages.loadingImageFailed);
}
}, imageOption);
});
}
}]);
return ImageLoader;
}(_component2.default);
module.exports = ImageLoader;
/***/ }),
/* 151 */
/***/ (function(module, exports) {
"use strict";
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; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Component interface
*/
/**
* Component interface
* @class
* @param {string} name - component name
* @param {Graphics} graphics - Graphics instance
* @ignore
*/
var Component = function () {
function Component(name, graphics) {
_classCallCheck(this, Component);
/**
* Component name
* @type {string}
*/
this.name = name;
/**
* Graphics instance
* @type {Graphics}
*/
this.graphics = graphics;
}
/**
* Fire Graphics event
* @param {Array} args - arguments
* @returns {Object} return value
*/
_createClass(Component, [{
key: "fire",
value: function fire() {
var context = this.graphics;
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return this.graphics.fire.apply(context, args);
}
/**
* Save image(background) of canvas
* @param {string} name - Name of image
* @param {fabric.Image} oImage - Fabric image instance
*/
}, {
key: "setCanvasImage",
value: function setCanvasImage(name, oImage) {
this.graphics.setCanvasImage(name, oImage);
}
/**
* Returns canvas element of fabric.Canvas[[lower-canvas]]
* @returns {HTMLCanvasElement}
*/
}, {
key: "getCanvasElement",
value: function getCanvasElement() {
return this.graphics.getCanvasElement();
}
/**
* Get fabric.Canvas instance
* @returns {fabric.Canvas}
*/
}, {
key: "getCanvas",
value: function getCanvas() {
return this.graphics.getCanvas();
}
/**
* Get canvasImage (fabric.Image instance)
* @returns {fabric.Image}
*/
}, {
key: "getCanvasImage",
value: function getCanvasImage() {
return this.graphics.getCanvasImage();
}
/**
* Get image name
* @returns {string}
*/
}, {
key: "getImageName",
value: function getImageName() {
return this.graphics.getImageName();
}
/**
* Get image editor
* @returns {ImageEditor}
*/
}, {
key: "getEditor",
value: function getEditor() {
return this.graphics.getEditor();
}
/**
* Return component name
* @returns {string}
*/
}, {
key: "getName",
value: function getName() {
return this.name;
}
/**
* Set image properties
* @param {Object} setting - Image properties
* @param {boolean} [withRendering] - If true, The changed image will be reflected in the canvas
*/
}, {
key: "setImageProperties",
value: function setImageProperties(setting, withRendering) {
this.graphics.setImageProperties(setting, withRendering);
}
/**
* Set canvas dimension - css only
* @param {Object} dimension - Canvas css dimension
*/
}, {
key: "setCanvasCssDimension",
value: function setCanvasCssDimension(dimension) {
this.graphics.setCanvasCssDimension(dimension);
}
/**
* Set canvas dimension - css only
* @param {Object} dimension - Canvas backstore dimension
*/
}, {
key: "setCanvasBackstoreDimension",
value: function setCanvasBackstoreDimension(dimension) {
this.graphics.setCanvasBackstoreDimension(dimension);
}
/**
* Adjust canvas dimension with scaling image
*/
}, {
key: "adjustCanvasDimension",
value: function adjustCanvasDimension() {
this.graphics.adjustCanvasDimension();
}
}]);
return Component;
}();
module.exports = Component;
/***/ }),
/* 152 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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 _fabric = __webpack_require__(105);
var _fabric2 = _interopRequireDefault(_fabric);
var _component = __webpack_require__(151);
var _component2 = _interopRequireDefault(_component);
var _cropzone = __webpack_require__(153);
var _cropzone2 = _interopRequireDefault(_cropzone);
var _consts = __webpack_require__(73);
var _util = __webpack_require__(72);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Image crop module (start cropping, end cropping)
*/
var MOUSE_MOVE_THRESHOLD = 10;
/**
* Cropper components
* @param {Graphics} graphics - Graphics instance
* @extends {Component}
* @class Cropper
* @ignore
*/
var Cropper = function (_Component) {
_inherits(Cropper, _Component);
function Cropper(graphics) {
_classCallCheck(this, Cropper);
/**
* Cropzone
* @type {Cropzone}
* @private
*/
var _this = _possibleConstructorReturn(this, (Cropper.__proto__ || Object.getPrototypeOf(Cropper)).call(this, _consts.componentNames.CROPPER, graphics));
_this._cropzone = null;
/**
* StartX of Cropzone
* @type {number}
* @private
*/
_this._startX = null;
/**
* StartY of Cropzone
* @type {number}
* @private
*/
_this._startY = null;
/**
* State whether shortcut key is pressed or not
* @type {boolean}
* @private
*/
_this._withShiftKey = false;
/**
* Listeners
* @type {object.<string, function>}
* @private
*/
_this._listeners = {
keydown: _this._onKeyDown.bind(_this),
keyup: _this._onKeyUp.bind(_this),
mousedown: _this._onFabricMouseDown.bind(_this),
mousemove: _this._onFabricMouseMove.bind(_this),
mouseup: _this._onFabricMouseUp.bind(_this)
};
return _this;
}
/**
* Start cropping
* @param {Object} options - params for setting
*/
_createClass(Cropper, [{
key: 'start',
value: function start(options) {
this.options = options || {};
if (this._cropzone) {
return;
}
var canvas = this.getCanvas();
canvas.forEachObject(function (obj) {
// {@link http://fabricjs.com/docs/fabric.Object.html#evented}
obj.evented = false;
});
this._cropzone = new _cropzone2.default(Object.assign({
left: -10,
top: -10,
width: 1,
height: 1,
strokeWidth: 0, // {@link https://github.com/kangax/fabric.js/issues/2860}
cornerSize: 10,
cornerColor: 'black',
fill: 'transparent',
hasRotatingPoint: false,
hasBorders: false,
lockScalingFlip: true,
lockRotation: true
}, options), this.graphics.cropSelectionStyle);
canvas.deactivateAll();
canvas.add(this._cropzone);
canvas.on('mouse:down', this._listeners.mousedown);
canvas.selection = false;
canvas.defaultCursor = 'crosshair';
canvas.setActiveObject(this._cropzone);
_fabric2.default.util.addListener(document, 'keydown', this._listeners.keydown);
_fabric2.default.util.addListener(document, 'keyup', this._listeners.keyup);
}
/**
* End cropping
*/
}, {
key: 'end',
value: function end() {
var canvas = this.getCanvas();
var cropzone = this._cropzone;
if (!cropzone) {
return;
}
cropzone.remove();
canvas.selection = true;
canvas.defaultCursor = 'default';
canvas.off('mouse:down', this._listeners.mousedown);
canvas.forEachObject(function (obj) {
obj.evented = true;
});
this._cropzone = null;
_fabric2.default.util.removeListener(document, 'keydown', this._listeners.keydown);
_fabric2.default.util.removeListener(document, 'keyup', this._listeners.keyup);
}
/**
* onMousedown handler in fabric canvas
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event
* @private
*/
}, {
key: '_onFabricMouseDown',
value: function _onFabricMouseDown(fEvent) {
var canvas = this.getCanvas();
if (fEvent.target) {
return;
}
canvas.selection = false;
var coord = canvas.getPointer(fEvent.e);
this._startX = coord.x;
this._startY = coord.y;
canvas.on({
'mouse:move': this._listeners.mousemove,
'mouse:up': this._listeners.mouseup
});
}
/**
* onMousemove handler in fabric canvas
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event
* @private
*/
}, {
key: '_onFabricMouseMove',
value: function _onFabricMouseMove(fEvent) {
var canvas = this.getCanvas();
var pointer = canvas.getPointer(fEvent.e);
var x = pointer.x,
y = pointer.y;
var cropzone = this._cropzone;
if (Math.abs(x - this._startX) + Math.abs(y - this._startY) > MOUSE_MOVE_THRESHOLD) {
cropzone.remove();
cropzone.set(this._calcRectDimensionFromPoint(x, y));
canvas.add(cropzone);
}
}
/**
* Get rect dimension setting from Canvas-Mouse-Position(x, y)
* @param {number} x - Canvas-Mouse-Position x
* @param {number} y - Canvas-Mouse-Position Y
* @returns {{left: number, top: number, width: number, height: number}}
* @private
*/
}, {
key: '_calcRectDimensionFromPoint',
value: function _calcRectDimensionFromPoint(x, y) {
var canvas = this.getCanvas();
var canvasWidth = canvas.getWidth();
var canvasHeight = canvas.getHeight();
var startX = this._startX;
var startY = this._startY;
var left = (0, _util.clamp)(x, 0, startX);
var top = (0, _util.clamp)(y, 0, startY);
var width = (0, _util.clamp)(x, startX, canvasWidth) - left; // (startX <= x(mouse) <= canvasWidth) - left
var height = (0, _util.clamp)(y, startY, canvasHeight) - top; // (startY <= y(mouse) <= canvasHeight) - top
if (this.options.lockProportion || this._withShiftKey) {
// make fixed ratio cropzone
if (width > height) {
height = width;
} else if (height > width) {
width = height;
}
if (startX >= x) {
left = startX - width;
}
if (startY >= y) {
top = startY - height;
}
}
return {
left: left,
top: top,
width: width,
height: height
};
}
/**
* onMouseup handler in fabric canvas
* @private
*/
}, {
key: '_onFabricMouseUp',
value: function _onFabricMouseUp() {
var cropzone = this._cropzone;
var listeners = this._listeners;
var canvas = this.getCanvas();
canvas.setActiveObject(cropzone);
canvas.off({
'mouse:move': listeners.mousemove,
'mouse:up': listeners.mouseup
});
}
/**
* Get cropped image data
* @param {Object} cropRect cropzone rect
* @param {Number} cropRect.left left position
* @param {Number} cropRect.top top position
* @param {Number} cropRect.width width
* @param {Number} cropRect.height height
* @returns {?{imageName: string, url: string}} cropped Image data
*/
}, {
key: 'getCroppedImageData',
value: function getCroppedImageData(cropRect) {
var canvas = this.getCanvas();
var containsCropzone = canvas.contains(this._cropzone);
if (!cropRect) {
return null;
}
if (containsCropzone) {
this._cropzone.remove();
}
var imageData = {
imageName: this.getImageName(),
url: canvas.toDataURL(cropRect)
};
if (containsCropzone) {
canvas.add(this._cropzone);
}
return imageData;
}
/**
* Get cropped rect
* @returns {Object} rect
*/
}, {
key: 'getCropzoneRect',
value: function getCropzoneRect() {
var cropzone = this._cropzone;
if (!cropzone.isValid()) {
return null;
}
return {
left: cropzone.getLeft(),
top: cropzone.getTop(),
width: cropzone.getWidth(),
height: cropzone.getHeight()
};
}
/**
* Keydown event handler
* @param {KeyboardEvent} e - Event object
* @private
*/
}, {
key: '_onKeyDown',
value: function _onKeyDown(e) {
if (e.keyCode === _consts.keyCodes.SHIFT) {
this._withShiftKey = true;
}
}
/**
* Keyup event handler
* @param {KeyboardEvent} e - Event object
* @private
*/
}, {
key: '_onKeyUp',
value: function _onKeyUp(e) {
if (e.keyCode === _consts.keyCodes.SHIFT) {
this._withShiftKey = false;
}
}
}]);
return Cropper;
}(_component2.default);
module.exports = Cropper;
/***/ }),
/* 153 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _tuiCodeSnippet = __webpack_require__(3);
var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet);
var _fabric = __webpack_require__(105);
var _fabric2 = _interopRequireDefault(_fabric);
var _util = __webpack_require__(72);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var CORNER_TYPE_TOP_LEFT = 'tl'; /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Cropzone extending fabric.Rect
*/
var CORNER_TYPE_TOP_RIGHT = 'tr';
var CORNER_TYPE_MIDDLE_TOP = 'mt';
var CORNER_TYPE_MIDDLE_LEFT = 'ml';
var CORNER_TYPE_MIDDLE_RIGHT = 'mr';
var CORNER_TYPE_MIDDLE_BOTTOM = 'mb';
var CORNER_TYPE_BOTTOM_LEFT = 'bl';
var CORNER_TYPE_BOTTOM_RIGHT = 'br';
/**
* Cropzone object
* Issue: IE7, 8(with excanvas)
* - Cropzone is a black zone without transparency.
* @class Cropzone
* @extends {fabric.Rect}
* @ignore
*/
var Cropzone = _fabric2.default.util.createClass(_fabric2.default.Rect, /** @lends Cropzone.prototype */{
/**
* Constructor
* @param {Object} options Options object
* @override
*/
initialize: function initialize(options, extendsOptions) {
options = _tuiCodeSnippet2.default.extend(options, extendsOptions);
options.type = 'cropzone';
this.callSuper('initialize', options);
this.options = options;
this.on({
'moving': this._onMoving,
'scaling': this._onScaling
});
},
/**
* Render Crop-zone
* @param {CanvasRenderingContext2D} ctx - Context
* @private
* @override
*/
_render: function _render(ctx) {
var cropzoneDashLineWidth = 7;
var cropzoneDashLineOffset = 7;
this.callSuper('_render', ctx);
// Calc original scale
var originalFlipX = this.flipX ? -1 : 1;
var originalFlipY = this.flipY ? -1 : 1;
var originalScaleX = originalFlipX / this.scaleX;
var originalScaleY = originalFlipY / this.scaleY;
// Set original scale
ctx.scale(originalScaleX, originalScaleY);
// Render outer rect
this._fillOuterRect(ctx, 'rgba(0, 0, 0, 0.55)');
if (this.options.lineWidth) {
this._fillInnerRect(ctx);
this._strokeBorder(ctx, 'rgb(255, 255, 255)', {
lineWidth: this.options.lineWidth
});
} else {
// Black dash line
this._strokeBorder(ctx, 'rgb(0, 0, 0)', {
lineDashWidth: cropzoneDashLineWidth
});
// White dash line
this._strokeBorder(ctx, 'rgb(255, 255, 255)', {
lineDashWidth: cropzoneDashLineWidth,
lineDashOffset: cropzoneDashLineOffset
});
}
// Reset scale
ctx.scale(1 / originalScaleX, 1 / originalScaleY);
},
/**
* Cropzone-coordinates with outer rectangle
*
* x0 x1 x2 x3
* y0 +--------------------------+
* |///////|//////////|///////| // <--- "Outer-rectangle"
* |///////|//////////|///////|
* y1 +-------+----------+-------+
* |///////| Cropzone |///////| Cropzone is the "Inner-rectangle"
* |///////| (0, 0) |///////| Center point (0, 0)
* y2 +-------+----------+-------+
* |///////|//////////|///////|
* |///////|//////////|///////|
* y3 +--------------------------+
*
* @typedef {{x: Array<number>, y: Array<number>}} cropzoneCoordinates
* @ignore
*/
/**
* Fill outer rectangle
* @param {CanvasRenderingContext2D} ctx - Context
* @param {string|CanvasGradient|CanvasPattern} fillStyle - Fill-style
* @private
*/
_fillOuterRect: function _fillOuterRect(ctx, fillStyle) {
var _getCoordinates = this._getCoordinates(ctx),
x = _getCoordinates.x,
y = _getCoordinates.y;
ctx.save();
ctx.fillStyle = fillStyle;
ctx.beginPath();
// Outer rectangle
// Numbers are +/-1 so that overlay edges don't get blurry.
ctx.moveTo(x[0] - 1, y[0] - 1);
ctx.lineTo(x[3] + 1, y[0] - 1);
ctx.lineTo(x[3] + 1, y[3] + 1);
ctx.lineTo(x[0] - 1, y[3] + 1);
ctx.lineTo(x[0] - 1, y[0] - 1);
ctx.closePath();
// Inner rectangle
ctx.moveTo(x[1], y[1]);
ctx.lineTo(x[1], y[2]);
ctx.lineTo(x[2], y[2]);
ctx.lineTo(x[2], y[1]);
ctx.lineTo(x[1], y[1]);
ctx.closePath();
ctx.fill();
ctx.restore();
},
/**
* Draw Inner grid line
* @param {CanvasRenderingContext2D} ctx - Context
* @private
*/
_fillInnerRect: function _fillInnerRect(ctx) {
var _getCoordinates2 = this._getCoordinates(ctx),
outerX = _getCoordinates2.x,
outerY = _getCoordinates2.y;
var x = this._caculateInnerPosition(outerX, (outerX[2] - outerX[1]) / 3);
var y = this._caculateInnerPosition(outerY, (outerY[2] - outerY[1]) / 3);
ctx.save();
ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)';
ctx.lineWidth = this.options.lineWidth;
ctx.beginPath();
ctx.moveTo(x[0], y[1]);
ctx.lineTo(x[3], y[1]);
ctx.moveTo(x[0], y[2]);
ctx.lineTo(x[3], y[2]);
ctx.moveTo(x[1], y[0]);
ctx.lineTo(x[1], y[3]);
ctx.moveTo(x[2], y[0]);
ctx.lineTo(x[2], y[3]);
ctx.stroke();
ctx.closePath();
ctx.restore();
},
/**
* Calculate Inner Position
* @param {Array} outer - outer position
* @param {number} size - interval for calcaulate
* @returns {Array} - inner position
* @private
*/
_caculateInnerPosition: function _caculateInnerPosition(outer, size) {
var position = [];
position[0] = outer[1];
position[1] = outer[1] + size;
position[2] = outer[1] + size * 2;
position[3] = outer[2];
return position;
},
/**
* Get coordinates
* @param {CanvasRenderingContext2D} ctx - Context
* @returns {cropzoneCoordinates} - {@link cropzoneCoordinates}
* @private
*/
_getCoordinates: function _getCoordinates(ctx) {
var width = this.getWidth(),
height = this.getHeight(),
halfWidth = width / 2,
halfHeight = height / 2,
left = this.getLeft(),
top = this.getTop(),
canvasEl = ctx.canvas; // canvas element, not fabric object
return {
x: _tuiCodeSnippet2.default.map([-(halfWidth + left), // x0
-halfWidth, // x1
halfWidth, // x2
halfWidth + (canvasEl.width - left - width) // x3
], Math.ceil),
y: _tuiCodeSnippet2.default.map([-(halfHeight + top), // y0
-halfHeight, // y1
halfHeight, // y2
halfHeight + (canvasEl.height - top - height) // y3
], Math.ceil)
};
},
/**
* Stroke border
* @param {CanvasRenderingContext2D} ctx - Context
* @param {string|CanvasGradient|CanvasPattern} strokeStyle - Stroke-style
* @param {number} lineDashWidth - Dash width
* @param {number} [lineDashOffset] - Dash offset
* @private
*/
_strokeBorder: function _strokeBorder(ctx, strokeStyle, _ref) {
var lineDashWidth = _ref.lineDashWidth,
lineDashOffset = _ref.lineDashOffset,
lineWidth = _ref.lineWidth;
var halfWidth = this.getWidth() / 2,
halfHeight = this.getHeight() / 2;
ctx.save();
ctx.strokeStyle = strokeStyle;
if (ctx.setLineDash) {
ctx.setLineDash([lineDashWidth, lineDashWidth]);
}
if (lineDashOffset) {
ctx.lineDashOffset = lineDashOffset;
}
if (lineWidth) {
ctx.lineWidth = lineWidth;
}
ctx.beginPath();
ctx.moveTo(-halfWidth, -halfHeight);
ctx.lineTo(halfWidth, -halfHeight);
ctx.lineTo(halfWidth, halfHeight);
ctx.lineTo(-halfWidth, halfHeight);
ctx.lineTo(-halfWidth, -halfHeight);
ctx.stroke();
ctx.restore();
},
/**
* onMoving event listener
* @private
*/
_onMoving: function _onMoving() {
var left = this.getLeft(),
top = this.getTop(),
width = this.getWidth(),
height = this.getHeight(),
maxLeft = this.canvas.getWidth() - width,
maxTop = this.canvas.getHeight() - height;
this.setLeft((0, _util.clamp)(left, 0, maxLeft));
this.setTop((0, _util.clamp)(top, 0, maxTop));
},
/**
* onScaling event listener
* @param {{e: MouseEvent}} fEvent - Fabric event
* @private
*/
_onScaling: function _onScaling(fEvent) {
var pointer = this.canvas.getPointer(fEvent.e),
settings = this._calcScalingSizeFromPointer(pointer);
// On scaling cropzone,
// change real width and height and fix scaleFactor to 1
this.scale(1).set(settings);
},
/**
* Calc scaled size from mouse pointer with selected corner
* @param {{x: number, y: number}} pointer - Mouse position
* @returns {Object} Having left or(and) top or(and) width or(and) height.
* @private
*/
_calcScalingSizeFromPointer: function _calcScalingSizeFromPointer(pointer) {
var pointerX = pointer.x,
pointerY = pointer.y,
tlScalingSize = this._calcTopLeftScalingSizeFromPointer(pointerX, pointerY),
brScalingSize = this._calcBottomRightScalingSizeFromPointer(pointerX, pointerY);
/*
* @todo: 일반 객체에서 shift 조합키를 누르면 free size scaling이 됨 --> 확인해볼것
* canvas.class.js // _scaleObject: function(...){...}
*/
return this._makeScalingSettings(tlScalingSize, brScalingSize);
},
/**
* Calc scaling size(position + dimension) from left-top corner
* @param {number} x - Mouse position X
* @param {number} y - Mouse position Y
* @returns {{top: number, left: number, width: number, height: number}}
* @private
*/
_calcTopLeftScalingSizeFromPointer: function _calcTopLeftScalingSizeFromPointer(x, y) {
var bottom = this.getHeight() + this.top,
right = this.getWidth() + this.left,
top = (0, _util.clamp)(y, 0, bottom - 1),
// 0 <= top <= (bottom - 1)
left = (0, _util.clamp)(x, 0, right - 1),
// 0 <= left <= (right - 1)
width = right - left,
height = bottom - top;
var result = {
top: top,
left: left,
width: width,
height: height
};
// When scaling "Top-Left corner": It fixes right and bottom coordinates
return result;
},
/**
* Calc scaling size from right-bottom corner
* @param {number} x - Mouse position X
* @param {number} y - Mouse position Y
* @returns {{width: number, height: number}}
* @private
*/
_calcBottomRightScalingSizeFromPointer: function _calcBottomRightScalingSizeFromPointer(x, y) {
var _canvas = this.canvas,
maxX = _canvas.width,
maxY = _canvas.height;
var left = this.left,
top = this.top;
// When scaling "Bottom-Right corner": It fixes left and top coordinates
var width = (0, _util.clamp)(x, left + 1, maxX) - left; // (width = x - left), (left + 1 <= x <= maxX)
var height = (0, _util.clamp)(y, top + 1, maxY) - top; // (height = y - top), (top + 1 <= y <= maxY)
var result = {
width: width,
height: height
};
return result;
},
/* eslint-disable complexity */
/**
* Make scaling settings
* @param {{width: number, height: number, left: number, top: number}} tl - Top-Left setting
* @param {{width: number, height: number}} br - Bottom-Right setting
* @returns {{width: ?number, height: ?number, left: ?number, top: ?number}} Position setting
* @private
*/
_makeScalingSettings: function _makeScalingSettings(tl, br) {
var tlWidth = tl.width;
var tlHeight = tl.height;
var brHeight = br.height;
var brWidth = br.width;
var tlLeft = tl.left;
var tlTop = tl.top;
var settings = void 0;
switch (this.__corner) {
case CORNER_TYPE_TOP_LEFT:
if (this.options.lockProportion) {
var ajwh = tl.width < tl.height ? tl.width : tl.height;
if (ajwh === tl.width) {
tl.top += tl.height - tl.width;
} else {
tl.left += tl.width - tl.height;
}
tl.width = ajwh;
tl.height = ajwh;
}
settings = tl;
break;
case CORNER_TYPE_TOP_RIGHT:
if (this.options.lockProportion) {
var _ajwh = brWidth > tlHeight ? tlHeight : brWidth;
if (_ajwh === brWidth) {
tlTop += tlHeight - brWidth;
}
tlHeight = _ajwh;
brWidth = _ajwh;
}
settings = {
width: brWidth,
height: tlHeight,
top: tlTop
};
break;
case CORNER_TYPE_BOTTOM_LEFT:
if (this.options.lockProportion) {
var _ajwh2 = tlWidth > brHeight ? brHeight : tlWidth;
if (_ajwh2 === brHeight) {
tlLeft += tlWidth - brHeight;
}
tlWidth = _ajwh2;
brHeight = _ajwh2;
}
settings = {
width: tlWidth,
height: brHeight,
left: tlLeft
};
break;
case CORNER_TYPE_BOTTOM_RIGHT:
if (this.options.lockProportion) {
var ajhw = br.height > br.width ? br.width : br.height;
br.height = ajhw;
br.width = ajhw;
}
settings = br;
break;
case CORNER_TYPE_MIDDLE_LEFT:
// TODO: lockProportion
settings = {
width: tlWidth,
left: tlLeft
};
break;
case CORNER_TYPE_MIDDLE_TOP:
// TODO: lockProportion
settings = {
height: tlHeight,
top: tlTop
};
break;
case CORNER_TYPE_MIDDLE_RIGHT:
// TODO: lockProportion
settings = {
width: brWidth
};
break;
case CORNER_TYPE_MIDDLE_BOTTOM:
// TODO: lockProportion
settings = {
height: brHeight
};
break;
default:
break;
}
return settings;
},
/* eslint-enable complexity */
/**
* Return the whether this cropzone is valid
* @returns {boolean}
*/
isValid: function isValid() {
return this.left >= 0 && this.top >= 0 && this.width > 0 && this.height > 0;
}
});
module.exports = Cropzone;
/***/ }),
/* 154 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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 _tuiCodeSnippet = __webpack_require__(3);
var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _component = __webpack_require__(151);
var _component2 = _interopRequireDefault(_component);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Image flip module
*/
var componentNames = _consts2.default.componentNames,
rejectMessages = _consts2.default.rejectMessages;
/**
* Flip
* @class Flip
* @param {Graphics} graphics - Graphics instance
* @extends {Component}
* @ignore
*/
var Flip = function (_Component) {
_inherits(Flip, _Component);
function Flip(graphics) {
_classCallCheck(this, Flip);
return _possibleConstructorReturn(this, (Flip.__proto__ || Object.getPrototypeOf(Flip)).call(this, componentNames.FLIP, graphics));
}
/**
* Get current flip settings
* @returns {{flipX: Boolean, flipY: Boolean}}
*/
_createClass(Flip, [{
key: 'getCurrentSetting',
value: function getCurrentSetting() {
var canvasImage = this.getCanvasImage();
return {
flipX: canvasImage.flipX,
flipY: canvasImage.flipY
};
}
/**
* Set flipX, flipY
* @param {{flipX: Boolean, flipY: Boolean}} newSetting - Flip setting
* @returns {jQuery.Deferred}
*/
}, {
key: 'set',
value: function set(newSetting) {
var setting = this.getCurrentSetting();
var isChangingFlipX = setting.flipX !== newSetting.flipX;
var isChangingFlipY = setting.flipY !== newSetting.flipY;
if (!isChangingFlipX && !isChangingFlipY) {
return _promise2.default.reject(rejectMessages.flip);
}
_tuiCodeSnippet2.default.extend(setting, newSetting);
this.setImageProperties(setting, true);
this._invertAngle(isChangingFlipX, isChangingFlipY);
this._flipObjects(isChangingFlipX, isChangingFlipY);
return _promise2.default.resolve({
flipX: setting.flipX,
flipY: setting.flipY,
angle: this.getCanvasImage().angle
});
}
/**
* Invert image angle for flip
* @param {boolean} isChangingFlipX - Change flipX
* @param {boolean} isChangingFlipY - Change flipY
*/
}, {
key: '_invertAngle',
value: function _invertAngle(isChangingFlipX, isChangingFlipY) {
var canvasImage = this.getCanvasImage();
var angle = canvasImage.angle;
if (isChangingFlipX) {
angle *= -1;
}
if (isChangingFlipY) {
angle *= -1;
}
canvasImage.setAngle(parseFloat(angle)).setCoords(); // parseFloat for -0 to 0
}
/**
* Flip objects
* @param {boolean} isChangingFlipX - Change flipX
* @param {boolean} isChangingFlipY - Change flipY
* @private
*/
}, {
key: '_flipObjects',
value: function _flipObjects(isChangingFlipX, isChangingFlipY) {
var canvas = this.getCanvas();
if (isChangingFlipX) {
canvas.forEachObject(function (obj) {
obj.set({
angle: parseFloat(obj.angle * -1), // parseFloat for -0 to 0
flipX: !obj.flipX,
left: canvas.width - obj.left
}).setCoords();
});
}
if (isChangingFlipY) {
canvas.forEachObject(function (obj) {
obj.set({
angle: parseFloat(obj.angle * -1), // parseFloat for -0 to 0
flipY: !obj.flipY,
top: canvas.height - obj.top
}).setCoords();
});
}
canvas.renderAll();
}
/**
* Reset flip settings
* @returns {jQuery.Deferred}
*/
}, {
key: 'reset',
value: function reset() {
return this.set({
flipX: false,
flipY: false
});
}
/**
* Flip x
* @returns {jQuery.Deferred}
*/
}, {
key: 'flipX',
value: function flipX() {
var current = this.getCurrentSetting();
return this.set({
flipX: !current.flipX,
flipY: current.flipY
});
}
/**
* Flip y
* @returns {jQuery.Deferred}
*/
}, {
key: 'flipY',
value: function flipY() {
var current = this.getCurrentSetting();
return this.set({
flipX: current.flipX,
flipY: !current.flipY
});
}
}]);
return Flip;
}(_component2.default);
module.exports = Flip;
/***/ }),
/* 155 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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 _fabric = __webpack_require__(105);
var _fabric2 = _interopRequireDefault(_fabric);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _component = __webpack_require__(151);
var _component2 = _interopRequireDefault(_component);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Image rotation module
*/
var componentNames = _consts2.default.componentNames;
/**
* Image Rotation component
* @class Rotation
* @extends {Component}
* @param {Graphics} graphics - Graphics instance
* @ignore
*/
var Rotation = function (_Component) {
_inherits(Rotation, _Component);
function Rotation(graphics) {
_classCallCheck(this, Rotation);
return _possibleConstructorReturn(this, (Rotation.__proto__ || Object.getPrototypeOf(Rotation)).call(this, componentNames.ROTATION, graphics));
}
/**
* Get current angle
* @returns {Number}
*/
_createClass(Rotation, [{
key: 'getCurrentAngle',
value: function getCurrentAngle() {
return this.getCanvasImage().angle;
}
/**
* Set angle of the image
*
* Do not call "this.setImageProperties" for setting angle directly.
* Before setting angle, The originX,Y of image should be set to center.
* See "http://fabricjs.com/docs/fabric.Object.html#setAngle"
*
* @param {number} angle - Angle value
* @returns {jQuery.Deferred}
*/
}, {
key: 'setAngle',
value: function setAngle(angle) {
var oldAngle = this.getCurrentAngle() % 360; // The angle is lower than 2*PI(===360 degrees)
angle %= 360;
var canvasImage = this.getCanvasImage();
var oldImageCenter = canvasImage.getCenterPoint();
canvasImage.setAngle(angle).setCoords();
this.adjustCanvasDimension();
var newImageCenter = canvasImage.getCenterPoint();
this._rotateForEachObject(oldImageCenter, newImageCenter, angle - oldAngle);
return _promise2.default.resolve(angle);
}
/**
* Rotate for each object
* @param {fabric.Point} oldImageCenter - Image center point before rotation
* @param {fabric.Point} newImageCenter - Image center point after rotation
* @param {number} angleDiff - Image angle difference after rotation
* @private
*/
}, {
key: '_rotateForEachObject',
value: function _rotateForEachObject(oldImageCenter, newImageCenter, angleDiff) {
var canvas = this.getCanvas();
var centerDiff = {
x: oldImageCenter.x - newImageCenter.x,
y: oldImageCenter.y - newImageCenter.y
};
canvas.forEachObject(function (obj) {
var objCenter = obj.getCenterPoint();
var radian = _fabric2.default.util.degreesToRadians(angleDiff);
var newObjCenter = _fabric2.default.util.rotatePoint(objCenter, oldImageCenter, radian);
obj.set({
left: newObjCenter.x - centerDiff.x,
top: newObjCenter.y - centerDiff.y,
angle: (obj.angle + angleDiff) % 360
});
obj.setCoords();
});
canvas.renderAll();
}
/**
* Rotate the image
* @param {number} additionalAngle - Additional angle
* @returns {jQuery.Deferred}
*/
}, {
key: 'rotate',
value: function rotate(additionalAngle) {
var current = this.getCurrentAngle();
return this.setAngle(current + additionalAngle);
}
}]);
return Rotation;
}(_component2.default);
module.exports = Rotation;
/***/ }),
/* 156 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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 _fabric = __webpack_require__(105);
var _fabric2 = _interopRequireDefault(_fabric);
var _component = __webpack_require__(151);
var _component2 = _interopRequireDefault(_component);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Free drawing module, Set brush
*/
/**
* FreeDrawing
* @class FreeDrawing
* @param {Graphics} graphics - Graphics instance
* @extends {Component}
* @ignore
*/
var FreeDrawing = function (_Component) {
_inherits(FreeDrawing, _Component);
function FreeDrawing(graphics) {
_classCallCheck(this, FreeDrawing);
/**
* Brush width
* @type {number}
*/
var _this = _possibleConstructorReturn(this, (FreeDrawing.__proto__ || Object.getPrototypeOf(FreeDrawing)).call(this, _consts2.default.componentNames.FREE_DRAWING, graphics));
_this.width = 12;
/**
* fabric.Color instance for brush color
* @type {fabric.Color}
*/
_this.oColor = new _fabric2.default.Color('rgba(0, 0, 0, 0.5)');
return _this;
}
/**
* Start free drawing mode
* @param {{width: ?number, color: ?string}} [setting] - Brush width & color
*/
_createClass(FreeDrawing, [{
key: 'start',
value: function start(setting) {
var canvas = this.getCanvas();
canvas.isDrawingMode = true;
this.setBrush(setting);
}
/**
* Set brush
* @param {{width: ?number, color: ?string}} [setting] - Brush width & color
*/
}, {
key: 'setBrush',
value: function setBrush(setting) {
setting = setting || {};
var isMosaic = setting.mosaic;
var brush = isMosaic ? this.getCanvas().MosaicDrawingBrush : this.getCanvas().freeDrawingBrush;
if (isMosaic) {
brush.blocksize = setting.blocksize || 10;
if (setting.isNew) {
brush.mosaicSign = new Date().getTime();
}
}
this.width = setting.width || this.width;
if (setting.color) {
this.oColor = new _fabric2.default.Color(setting.color);
}
brush.width = this.width;
brush.color = this.oColor.toRgba();
this.getCanvas().freeDrawingBrush = brush;
}
/**
* End free drawing mode
*/
}, {
key: 'end',
value: function end() {
var canvas = this.getCanvas();
canvas.isDrawingMode = false;
}
}]);
return FreeDrawing;
}(_component2.default);
module.exports = FreeDrawing;
/***/ }),
/* 157 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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 _fabric = __webpack_require__(105);
var _fabric2 = _interopRequireDefault(_fabric);
var _component = __webpack_require__(151);
var _component2 = _interopRequireDefault(_component);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Free drawing module, Set brush
*/
var eventNames = _consts2.default.eventNames;
/**
* Line
* @class Line
* @param {Graphics} graphics - Graphics instance
* @extends {Component}
* @ignore
*/
var Line = function (_Component) {
_inherits(Line, _Component);
function Line(graphics) {
_classCallCheck(this, Line);
/**
* Brush width
* @type {number}
* @private
*/
var _this = _possibleConstructorReturn(this, (Line.__proto__ || Object.getPrototypeOf(Line)).call(this, _consts2.default.componentNames.LINE, graphics));
_this._width = 12;
/**
* fabric.Color instance for brush color
* @type {fabric.Color}
* @private
*/
_this._oColor = new _fabric2.default.Color('rgba(0, 0, 0, 0.5)');
/**
* Listeners
* @type {object.<string, function>}
* @private
*/
_this._listeners = {
mousedown: _this._onFabricMouseDown.bind(_this),
mousemove: _this._onFabricMouseMove.bind(_this),
mouseup: _this._onFabricMouseUp.bind(_this)
};
return _this;
}
/**
* Start drawing line mode
* @param {{width: ?number, color: ?string}} [setting] - Brush width & color
*/
_createClass(Line, [{
key: 'start',
value: function start(setting) {
var canvas = this.getCanvas();
canvas.defaultCursor = 'crosshair';
canvas.selection = false;
this.setBrush(setting);
canvas.forEachObject(function (obj) {
obj.set({
evented: false
});
});
canvas.on({
'mouse:down': this._listeners.mousedown
});
}
/**
* Set brush
* @param {{width: ?number, color: ?string}} [setting] - Brush width & color
*/
}, {
key: 'setBrush',
value: function setBrush(setting) {
var brush = this.getCanvas().freeDrawingBrush;
setting = setting || {};
this._width = setting.width || this._width;
if (setting.color) {
this._oColor = new _fabric2.default.Color(setting.color);
}
brush.width = this._width;
brush.color = this._oColor.toRgba();
}
/**
* End drawing line mode
*/
}, {
key: 'end',
value: function end() {
var canvas = this.getCanvas();
canvas.defaultCursor = 'default';
canvas.selection = true;
canvas.forEachObject(function (obj) {
obj.set({
evented: true
});
});
canvas.off('mouse:down', this._listeners.mousedown);
}
/**
* Mousedown event handler in fabric canvas
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object
* @private
*/
}, {
key: '_onFabricMouseDown',
value: function _onFabricMouseDown(fEvent) {
var canvas = this.getCanvas();
var pointer = canvas.getPointer(fEvent.e);
var points = [pointer.x, pointer.y, pointer.x, pointer.y];
this._line = new _fabric2.default.Line(points, {
stroke: this._oColor.toRgba(),
strokeWidth: this._width,
evented: false
});
this._line.set(_consts2.default.fObjectOptions.SELECTION_STYLE);
canvas.add(this._line);
canvas.on({
'mouse:move': this._listeners.mousemove,
'mouse:up': this._listeners.mouseup
});
}
/**
* Mousemove event handler in fabric canvas
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object
* @private
*/
}, {
key: '_onFabricMouseMove',
value: function _onFabricMouseMove(fEvent) {
var canvas = this.getCanvas();
var pointer = canvas.getPointer(fEvent.e);
this._line.set({
x2: pointer.x,
y2: pointer.y
});
this._line.setCoords();
canvas.renderAll();
}
/**
* Mouseup event handler in fabric canvas
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object
* @private
*/
}, {
key: '_onFabricMouseUp',
value: function _onFabricMouseUp() {
var canvas = this.getCanvas();
var params = this.graphics.createObjectProperties(this._line);
this.fire(eventNames.ADD_OBJECT, params);
this._line = null;
canvas.off({
'mouse:move': this._listeners.mousemove,
'mouse:up': this._listeners.mouseup
});
}
}]);
return Line;
}(_component2.default);
module.exports = Line;
/***/ }),
/* 158 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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 _fabric = __webpack_require__(105);
var _fabric2 = _interopRequireDefault(_fabric);
var _tuiCodeSnippet = __webpack_require__(3);
var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _component = __webpack_require__(151);
var _component2 = _interopRequireDefault(_component);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
var _util = __webpack_require__(72);
var _util2 = _interopRequireDefault(_util);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Text module
*/
var events = _consts2.default.eventNames;
var defaultStyles = {
fill: '#000000',
cornerSize: 24,
cornerStyle: 'editor',
hasRotatingPoint: false,
borderColor: '#fff',
borderLineWidth: 2,
left: 0,
top: 0
};
var resetStyles = {
fill: '#000000',
fontStyle: 'normal',
fontWeight: 'normal',
textAlign: 'left',
textDecoraiton: ''
};
var browser = _tuiCodeSnippet2.default.browser;
var TEXTAREA_CLASSNAME = 'tui-image-eidtor-textarea';
var TEXTAREA_STYLES = _util2.default.makeStyleText({
position: 'absolute',
padding: 0,
display: 'none',
border: '1px dotted red',
overflow: 'hidden',
resize: 'none',
outline: 'none',
'border-radius': 0,
'background-color': 'transparent',
'-webkit-appearance': 'none',
'z-index': 9999,
'white-space': 'pre'
});
var EXTRA_PIXEL_LINEHEIGHT = 0.1;
var DBCLICK_TIME = 500;
/**
* Text
* @class Text
* @param {Graphics} graphics - Graphics instance
* @extends {Component}
* @ignore
*/
var Text = function (_Component) {
_inherits(Text, _Component);
function Text(graphics) {
_classCallCheck(this, Text);
/**
* Default text style
* @type {Object}
*/
var _this = _possibleConstructorReturn(this, (Text.__proto__ || Object.getPrototypeOf(Text)).call(this, _consts2.default.componentNames.TEXT, graphics));
_this._defaultStyles = defaultStyles;
/**
* Selected state
* @type {boolean}
*/
_this._isSelected = false;
/**
* Selected text object
* @type {Object}
*/
_this._selectedObj = {};
_this._movingObj = {};
_this._isMoving = false;
/**
* Editing text object
* @type {Object}
*/
_this._editingObj = {};
/**
* Listeners for fabric event
* @type {Object}
*/
_this._listeners = {
mousedown: _this._onFabricMouseDown.bind(_this),
select: _this._onFabricSelect.bind(_this),
selectClear: _this._onFabricSelectClear.bind(_this),
scaling: _this._onFabricScaling.bind(_this)
};
/**
* Textarea element for editing
* @type {HTMLElement}
*/
_this._textarea = null;
/**
* Ratio of current canvas
* @type {number}
*/
_this._ratio = 1;
/**
* Last click time
* @type {Date}
*/
_this._lastClickTime = new Date().getTime();
/**
* Text object infos before editing
* @type {Object}
*/
_this._editingObjInfos = {};
/**
* Previous state of editing
* @type {boolean}
*/
_this.isPrevEditing = false;
_this.readyToEdit = false;
/**
* use itext
* @type {boolean}
*/
_this.useItext = graphics.useItext;
return _this;
}
/**
* Start input text mode
* @param {Object} options - params for setting
*/
_createClass(Text, [{
key: 'start',
value: function start(options) {
var canvas = this.getCanvas();
this.options = options;
canvas.selection = false;
canvas.defaultCursor = 'text';
canvas.on({
'mouse:down': this._listeners.mousedown,
'object:selected': this._listeners.select,
'before:selection:cleared': this._listeners.selectClear,
'object:scaling': this._listeners.scaling,
'text:editing': this._listeners.modify
});
if (this.useItext) {
canvas.forEachObject(function (obj) {
if (obj.type === 'i-text') {
obj.set({
left: obj.left - obj.width / 2,
top: obj.top - obj.height / 2,
originX: 'left',
originY: 'top'
});
}
});
} else {
this._createTextarea();
}
this.setCanvasRatio();
}
/**
* End input text mode
*/
}, {
key: 'end',
value: function end() {
var canvas = this.getCanvas();
canvas.selection = true;
canvas.defaultCursor = 'default';
if (this.useItext) {
canvas.forEachObject(function (obj) {
if (obj.type === 'i-text') {
if (obj.text === '') {
obj.remove();
} else {
obj.set({
left: obj.left + obj.width / 2,
top: obj.top + obj.height / 2,
originX: 'center',
originY: 'center'
});
}
}
});
} else {
canvas.deactivateAllWithDispatch();
this._removeTextarea();
}
canvas.off({
'mouse:down': this._listeners.mousedown,
'object:selected': this._listeners.select,
'before:selection:cleared': this._listeners.selectClear,
'object:scaling': this._listeners.scaling,
'text:editing': this._listeners.modify
});
}
/**
* Add new text on canvas image
* @param {string} text - Initial input text
* @param {Object} options - Options for generating text
* @param {Object} [options.styles] Initial styles
* @param {string} [options.styles.fill] Color
* @param {string} [options.styles.fontFamily] Font type for text
* @param {number} [options.styles.fontSize] Size
* @param {string} [options.styles.fontStyle] Type of inclination (normal / italic)
* @param {string} [options.styles.fontWeight] Type of thicker or thinner looking (normal / bold)
* @param {string} [options.styles.textAlign] Type of text align (left / center / right)
* @param {string} [options.styles.textDecoraiton] Type of line (underline / line-throgh / overline)
* @param {{x: number, y: number}} [options.position] - Initial position
* @returns {Promise}
*/
}, {
key: 'add',
value: function add(text, options) {
var _this2 = this;
return new _promise2.default(function (resolve) {
var canvas = _this2.getCanvas();
var newText = null;
var selectionStyle = _consts2.default.fObjectOptions.SELECTION_STYLE;
var styles = _this2._defaultStyles;
_this2._setInitPos(options.position);
if (options.styles) {
styles = _tuiCodeSnippet2.default.extend(styles, options.styles);
}
styles.cornerSize = options.cornerSize || 24;
if (_this2.useItext) {
newText = new _fabric2.default.IText(text, styles);
selectionStyle = _tuiCodeSnippet2.default.extend({}, selectionStyle, {
originX: 'left',
originY: 'top'
});
} else {
newText = new _fabric2.default.Text(text, styles);
newText.setControlsVisibility({
bl: false,
mb: false,
ml: false,
mr: false,
mt: false,
tl: false
});
}
newText.set(selectionStyle);
newText.on({
mouseup: _this2._onFabricMouseUp.bind(_this2),
moving: _this2._onFabricMoving.bind(_this2),
rotating: _this2._onFabricMoving.bind(_this2), // 当做移动统一处理
scaling: _this2._onFabricMoving.bind(_this2) // 当做移动统一处理
});
canvas.add(newText);
if (!canvas.getActiveObject()) {
if (styles.outerDecoration) {
newText.on('render:success', renderHandler);
} else {
canvas.setActiveObject(newText);
if (options.initEdit) {
newText.readyToEdit = true;
}
}
}
function renderHandler() {
newText.off('render:success', renderHandler);
// 等待newText渲染结束
setTimeout(function () {
canvas.setActiveObject(newText);
}, 100);
if (options.initEdit) {
newText.readyToEdit = true;
}
}
_this2.isPrevEditing = true;
resolve(_this2.graphics.createObjectProperties(newText));
});
}
/**
* Change text of activate object on canvas image
* @param {Object} activeObj - Current selected text object
* @param {string} text - Changed text
* @returns {Promise}
*/
}, {
key: 'change',
value: function change(activeObj, text) {
var _this3 = this;
return new _promise2.default(function (resolve) {
activeObj.set('text', text);
_this3.getCanvas().renderAll();
resolve();
});
}
/**
* Set style
* @param {Object} activeObj - Current selected text object
* @param {Object} styleObj - Initial styles
* @param {string} [styleObj.fill] Color
* @param {string} [styleObj.fontFamily] Font type for text
* @param {number} [styleObj.fontSize] Size
* @param {string} [styleObj.fontStyle] Type of inclination (normal / italic)
* @param {string} [styleObj.fontWeight] Type of thicker or thinner looking (normal / bold)
* @param {string} [styleObj.textAlign] Type of text align (left / center / right)
* @param {string} [styleObj.textDecoraiton] Type of line (underline / line-throgh / overline)
* @param {Boolean} notReset - reset flag
* @returns {Promise}
*/
}, {
key: 'setStyle',
value: function setStyle(activeObj, styleObj, notReset) {
var _this4 = this;
return new _promise2.default(function (resolve) {
if (!notReset) {
_tuiCodeSnippet2.default.forEach(styleObj, function (val, key) {
if (activeObj[key] === val) {
styleObj[key] = resetStyles[key] || '';
}
}, _this4);
}
activeObj.set(styleObj);
_this4.getCanvas().renderAll();
resolve();
});
}
/**
* setText function
* @param {string} text new text
*/
}, {
key: 'setText',
value: function setText(text) {
this._editingObj.setText(text);
}
/**
* Get the text
* @param {Object} activeObj - Current selected text object
* @returns {String} text
*/
}, {
key: 'getText',
value: function getText(activeObj) {
return activeObj.getText();
}
/**
* Set infos of the current selected object
* @param {fabric.Text} obj - Current selected text object
* @param {boolean} state - State of selecting
*/
}, {
key: 'setSelectedInfo',
value: function setSelectedInfo(obj, state) {
this._selectedObj = obj;
this._isSelected = state;
}
/**
* Set infos of current moving object
* @param {fabric.Text} obj - Current moving text object
* @param {boolean} state - State of moving
*/
}, {
key: 'setMovingInfo',
value: function setMovingInfo(obj, state) {
this._movingObj = obj;
this._isMoving = state;
}
/**
* get moving state
* @returns {boolean} state - State of moving
*/
}, {
key: 'isMoving',
value: function isMoving() {
return this._isMoving;
}
/**
* Whether object is selected or not
* @returns {boolean} State of selecting
*/
}, {
key: 'isSelected',
value: function isSelected() {
return this._isSelected;
}
/**
* Get current selected text object
* @returns {fabric.Text} Current selected text object
*/
}, {
key: 'getSelectedObj',
value: function getSelectedObj() {
return this._selectedObj;
}
/**
* Set ratio value of canvas
*/
}, {
key: 'setCanvasRatio',
value: function setCanvasRatio() {
var canvasElement = this.getCanvasElement();
var cssWidth = parseInt(canvasElement.style.maxWidth, 10);
var originWidth = canvasElement.width;
var ratio = originWidth / cssWidth;
this._ratio = ratio;
}
/**
* Get ratio value of canvas
* @returns {number} Ratio value
*/
}, {
key: 'getCanvasRatio',
value: function getCanvasRatio() {
return this._ratio;
}
/**
* Set initial position on canvas image
* @param {{x: number, y: number}} [position] - Selected position
* @private
*/
}, {
key: '_setInitPos',
value: function _setInitPos(position) {
position = position || this.getCanvasImage().getCenterPoint();
this._defaultStyles.left = position.x;
this._defaultStyles.top = position.y;
}
/**
* Create textarea element on canvas container
* @private
*/
}, {
key: '_createTextarea',
value: function _createTextarea() {
var container = this.getCanvasElement().parentNode;
var textarea = document.createElement('textarea');
textarea.className = TEXTAREA_CLASSNAME;
textarea.setAttribute('style', TEXTAREA_STYLES);
textarea.setAttribute('wrap', 'off');
container.appendChild(textarea);
this._textarea = textarea;
this._listeners = _tuiCodeSnippet2.default.extend(this._listeners, {
input: this._onInput.bind(this),
keydown: this._onKeyDown.bind(this),
blur: this._onBlur.bind(this),
scroll: this._onScroll.bind(this)
});
if (browser.msie && browser.version === 9) {
_fabric2.default.util.addListener(textarea, 'keydown', this._listeners.keydown);
} else {
_fabric2.default.util.addListener(textarea, 'input', this._listeners.input);
}
_fabric2.default.util.addListener(textarea, 'blur', this._listeners.blur);
_fabric2.default.util.addListener(textarea, 'scroll', this._listeners.scroll);
}
/**
* Remove textarea element on canvas container
* @private
*/
}, {
key: '_removeTextarea',
value: function _removeTextarea() {
var container = this.getCanvasElement().parentNode;
var textarea = container.querySelector('textarea');
container.removeChild(textarea);
this._textarea = null;
if (browser.msie && browser.version < 10) {
_fabric2.default.util.removeListener(textarea, 'keydown', this._listeners.keydown);
} else {
_fabric2.default.util.removeListener(textarea, 'input', this._listeners.input);
}
_fabric2.default.util.removeListener(textarea, 'blur', this._listeners.blur);
_fabric2.default.util.removeListener(textarea, 'scroll', this._listeners.scroll);
}
/**
* Input event handler
* @private
*/
}, {
key: '_onInput',
value: function _onInput() {
var ratio = this.getCanvasRatio();
var obj = this._editingObj;
var textareaStyle = this._textarea.style;
textareaStyle.width = Math.ceil(obj.getWidth() / ratio) + 'px';
textareaStyle.height = Math.ceil(obj.getHeight() / ratio) + 'px';
}
/**
* Keydown event handler
* @private
*/
}, {
key: '_onKeyDown',
value: function _onKeyDown() {
var _this5 = this;
var ratio = this.getCanvasRatio();
var obj = this._editingObj;
var textareaStyle = this._textarea.style;
setTimeout(function () {
obj.setText(_this5._textarea.value);
textareaStyle.width = Math.ceil(obj.getWidth() / ratio) + 'px';
textareaStyle.height = Math.ceil(obj.getHeight() / ratio) + 'px';
}, 0);
}
/**
* Blur event handler
* @private
*/
}, {
key: '_onBlur',
value: function _onBlur() {
var ratio = this.getCanvasRatio();
var editingObj = this._editingObj;
var editingObjInfos = this._editingObjInfos;
var textContent = this._textarea.value;
var transWidth = editingObj.getWidth() / ratio - editingObjInfos.width / ratio;
var transHeight = editingObj.getHeight() / ratio - editingObjInfos.height / ratio;
if (ratio === 1) {
transWidth /= 2;
transHeight /= 2;
}
this._textarea.style.display = 'none';
editingObj.set({
left: editingObjInfos.left + transWidth,
top: editingObjInfos.top + transHeight
});
if (textContent.length) {
this.getCanvas().add(editingObj);
var params = {
id: _tuiCodeSnippet2.default.stamp(editingObj),
type: editingObj.type,
text: textContent
};
this.fire(events.TEXT_CHANGED, params);
}
}
/**
* Scroll event handler
* @private
*/
}, {
key: '_onScroll',
value: function _onScroll() {
this._textarea.scrollLeft = 0;
this._textarea.scrollTop = 0;
}
/**
* Fabric scaling event handler
* @param {fabric.Event} fEvent - Current scaling event on selected object
* @private
*/
}, {
key: '_onFabricScaling',
value: function _onFabricScaling(fEvent) {
var obj = fEvent.target; // eslint-disable-line
// const obj = fEvent.target;
// const scalingSize = obj.getFontSize() * obj.getScaleY();
// obj.setFontSize(scalingSize);
// obj.setScaleX(1);
// obj.setScaleY(1);
}
/**
* onSelectClear handler in fabric canvas
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event
* @private
*/
}, {
key: '_onFabricSelectClear',
value: function _onFabricSelectClear(fEvent) {
var obj = this.getSelectedObj();
this.isPrevEditing = true;
this.setSelectedInfo(fEvent.target, false);
if (obj) {
// obj is empty object at initial time, will be set fabric object
if (obj.text === '') {
obj.remove();
}
}
}
/**
* onSelect handler in fabric canvas
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event
* @private
*/
}, {
key: '_onFabricSelect',
value: function _onFabricSelect(fEvent) {
this.isPrevEditing = true;
if (fEvent.target !== this._selectedObj) {
this._selectedObj.readyToEdit = false;
}
this.setSelectedInfo(fEvent.target, true);
}
/**
* Fabric 'mousedown' event handler
* @param {fabric.Event} fEvent - Current mousedown event on selected object
* @private
*/
}, {
key: '_onFabricMouseDown',
value: function _onFabricMouseDown(fEvent) {
var obj = fEvent.target;
if (obj !== this._selectedObj) {
this._selectedObj.readyToEdit = false;
this._selectedObj = {};
}
if (obj && !obj.isType('text')) {
this._selectedObj.readyToEdit = false;
return;
}
if (this.isPrevEditing) {
this.isPrevEditing = false;
return;
}
this._fireAddText(fEvent);
}
/**
* Fire 'addText' event if object is not selected.
* @param {fabric.Event} fEvent - Current mousedown event on selected object
* @private
*/
}, {
key: '_fireAddText',
value: function _fireAddText(fEvent) {
var obj = fEvent.target;
var e = fEvent.e || {};
var originPointer = this.getCanvas().getPointer(e);
if (!obj) {
this.fire(events.ADD_TEXT, {
originPosition: {
x: originPointer.x,
y: originPointer.y
},
clientPosition: {
x: e.clientX || 0,
y: e.clientY || 0
}
});
}
}
/**
* Fabric objectMoving event handler
* @param {fabric.Event} fEvent - Current mousedown event on selected object
* @private
*/
}, {
key: '_onFabricMoving',
value: function _onFabricMoving(fEvent) {
this.setMovingInfo(fEvent.target, true);
}
/**
* Fabric mouseup event handler
* @param {fabric.Event} fEvent - Current mousedown event on selected object
* @private
*/
}, {
key: '_onFabricMouseUp',
value: function _onFabricMouseUp(fEvent) {
if (!this.isMoving()) {
if (this._selectedObj.__fe_id === fEvent.target.__fe_id && this._selectedObj.readyToEdit) {
this.fire(events.TEXT_EDITING, fEvent.target); // fire editing text event with target
} else {
this._selectedObj.readyToEdit = true;
}
}
this.setMovingInfo(fEvent.target, false);
}
/**
* Get state of firing double click event
* @param {Date} newClickTime - Current clicked time
* @returns {boolean} Whether double clicked or not
* @private
*/
}, {
key: '_isDoubleClick',
value: function _isDoubleClick(newClickTime) {
return newClickTime - this._lastClickTime < DBCLICK_TIME;
}
/**
* Change state of text object for editing
* @param {fabric.Text} obj - Text object fired event
* @private
*/
}, {
key: '_changeToEditingMode',
value: function _changeToEditingMode(obj) {
var ratio = this.getCanvasRatio();
var textareaStyle = this._textarea.style;
this.isPrevEditing = true;
obj.remove();
this._editingObj = obj;
this._textarea.value = obj.getText();
this._editingObjInfos = {
left: this._editingObj.getLeft(),
top: this._editingObj.getTop(),
width: this._editingObj.getWidth(),
height: this._editingObj.getHeight()
};
textareaStyle.display = 'block';
textareaStyle.left = obj.oCoords.tl.x / ratio + 'px';
textareaStyle.top = obj.oCoords.tl.y / ratio + 'px';
textareaStyle.width = Math.ceil(obj.getWidth() / ratio) + 'px';
textareaStyle.height = Math.ceil(obj.getHeight() / ratio) + 'px';
textareaStyle.transform = 'rotate(' + obj.getAngle() + 'deg)';
textareaStyle.color = obj.getFill();
textareaStyle['font-size'] = obj.getFontSize() / ratio + 'px';
textareaStyle['font-family'] = obj.getFontFamily();
textareaStyle['font-style'] = obj.getFontStyle();
textareaStyle['font-weight'] = obj.getFontWeight();
textareaStyle['text-align'] = obj.getTextAlign();
textareaStyle['line-height'] = obj.getLineHeight() + EXTRA_PIXEL_LINEHEIGHT;
textareaStyle['transform-origin'] = 'left top';
this._textarea.focus();
}
}]);
return Text;
}(_component2.default);
module.exports = Text;
/***/ }),
/* 159 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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 _fabric = __webpack_require__(105);
var _fabric2 = _interopRequireDefault(_fabric);
var _tuiCodeSnippet = __webpack_require__(3);
var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _component = __webpack_require__(151);
var _component2 = _interopRequireDefault(_component);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Add icon module
*/
var events = _consts2.default.eventNames;
var rejectMessages = _consts2.default.rejectMessages;
var pathMap = {
arrow: 'M 0 90 H 105 V 120 L 160 60 L 105 0 V 30 H 0 Z',
cancel: 'M 0 30 L 30 60 L 0 90 L 30 120 L 60 90 L 90 120 L 120 90 ' + 'L 90 60 L 120 30 L 90 0 L 60 30 L 30 0 Z'
};
/**
* Icon
* @class Icon
* @param {Graphics} graphics - Graphics instance
* @extends {Component}
* @ignore
*/
var Icon = function (_Component) {
_inherits(Icon, _Component);
function Icon(graphics) {
_classCallCheck(this, Icon);
/**
* Default icon color
* @type {string}
*/
var _this = _possibleConstructorReturn(this, (Icon.__proto__ || Object.getPrototypeOf(Icon)).call(this, _consts2.default.componentNames.ICON, graphics));
_this._oColor = '#000000';
/**
* Path value of each icon type
* @type {Object}
*/
_this._pathMap = pathMap;
/**
* Option to add icon to drag.
* @type {boolean}
*/
_this.useDragAddIcon = graphics.useDragAddIcon;
return _this;
}
/**
* Add icon
* @param {string} type - Icon type
* @param {Object} options - Icon options
* @param {string} [options.fill] - Icon foreground color
* @param {string} [options.left] - Icon x position
* @param {string} [options.top] - Icon y position
* @returns {Promise}
*/
_createClass(Icon, [{
key: 'add',
value: function add(type, options) {
var _this2 = this;
return new _promise2.default(function (resolve, reject) {
var canvas = _this2.getCanvas();
var path = _this2._pathMap[type];
var selectionStyle = _consts2.default.fObjectOptions.SELECTION_STYLE;
var registerdIcon = Object.keys(_consts2.default.defaultIconPath).indexOf(type) >= 0;
var useDragAddIcon = _this2.useDragAddIcon && registerdIcon;
var icon = path ? _this2._createIcon(path) : null;
if (!icon) {
reject(rejectMessages.invalidParameters);
}
icon.set(_tuiCodeSnippet2.default.extend({
type: 'icon',
fill: _this2._oColor
}, selectionStyle, options, _this2.graphics.controlStyle));
canvas.add(icon).setActiveObject(icon);
if (useDragAddIcon) {
_this2._addWithDragEvent(canvas);
}
resolve(_this2.graphics.createObjectProperties(icon));
});
}
/**
* Added icon drag event
* @param {fabric.Canvas} canvas - Canvas instance
* @private
*/
}, {
key: '_addWithDragEvent',
value: function _addWithDragEvent(canvas) {
var _this3 = this;
canvas.on({
'mouse:move': function mouseMove(fEvent) {
canvas.selection = false;
_this3.fire(events.ICON_CREATE_RESIZE, {
moveOriginPointer: canvas.getPointer(fEvent.e)
});
},
'mouse:up': function mouseUp(fEvent) {
_this3.fire(events.ICON_CREATE_END, {
moveOriginPointer: canvas.getPointer(fEvent.e)
});
canvas.defaultCursor = 'default';
canvas.off('mouse:up');
canvas.off('mouse:move');
canvas.selection = true;
}
});
}
/**
* Register icon paths
* @param {{key: string, value: string}} pathInfos - Path infos
*/
}, {
key: 'registerPaths',
value: function registerPaths(pathInfos) {
var _this4 = this;
_tuiCodeSnippet2.default.forEach(pathInfos, function (path, type) {
_this4._pathMap[type] = path;
}, this);
}
/**
* Set icon object color
* @param {string} color - Color to set
* @param {fabric.Path}[obj] - Current activated path object
*/
}, {
key: 'setColor',
value: function setColor(color, obj) {
this._oColor = color;
if (obj && obj.get('type') === 'icon') {
obj.setFill(this._oColor);
this.getCanvas().renderAll();
}
}
/**
* Get icon color
* @param {fabric.Path}[obj] - Current activated path object
* @returns {string} color
*/
}, {
key: 'getColor',
value: function getColor(obj) {
return obj.fill;
}
/**
* Create icon object
* @param {string} path - Path value to create icon
* @returns {fabric.Path} Path object
*/
}, {
key: '_createIcon',
value: function _createIcon(path) {
return new _fabric2.default.Path(path);
}
}]);
return Icon;
}(_component2.default);
module.exports = Icon;
/***/ }),
/* 160 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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 _tuiCodeSnippet = __webpack_require__(3);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _fabric = __webpack_require__(105);
var _fabric2 = _interopRequireDefault(_fabric);
var _component = __webpack_require__(151);
var _component2 = _interopRequireDefault(_component);
var _mask = __webpack_require__(161);
var _mask2 = _interopRequireDefault(_mask);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
var _blur = __webpack_require__(162);
var _blur2 = _interopRequireDefault(_blur);
var _sharpen = __webpack_require__(163);
var _sharpen2 = _interopRequireDefault(_sharpen);
var _emboss = __webpack_require__(164);
var _emboss2 = _interopRequireDefault(_emboss);
var _colorFilter = __webpack_require__(165);
var _colorFilter2 = _interopRequireDefault(_colorFilter);
var _oldMaker = __webpack_require__(166);
var _oldMaker2 = _interopRequireDefault(_oldMaker);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Add filter module
*/
var rejectMessages = _consts2.default.rejectMessages;
var filters = _fabric2.default.Image.filters;
filters.Mask = _mask2.default;
filters.Blur = _blur2.default;
filters.Sharpen = _sharpen2.default;
filters.Emboss = _emboss2.default;
filters.ColorFilter = _colorFilter2.default;
filters.OldMaker = _oldMaker2.default;
/**
* Filter
* @class Filter
* @param {Graphics} graphics - Graphics instance
* @extends {Component}
* @ignore
*/
var Filter = function (_Component) {
_inherits(Filter, _Component);
function Filter(graphics) {
_classCallCheck(this, Filter);
return _possibleConstructorReturn(this, (Filter.__proto__ || Object.getPrototypeOf(Filter)).call(this, _consts2.default.componentNames.FILTER, graphics));
}
/**
* Add filter to source image (a specific filter is added on fabric.js)
* @param {string} type - Filter type
* @param {Object} [options] - Options of filter
* @returns {Promise}
*/
_createClass(Filter, [{
key: 'add',
value: function add(type, options) {
var _this2 = this;
return new _promise2.default(function (resolve, reject) {
var sourceImg = _this2._getSourceImage();
var canvas = _this2.getCanvas();
var imgFilter = _this2._getFilter(sourceImg, type);
if (!imgFilter) {
imgFilter = _this2._createFilter(sourceImg, type, options);
}
if (!imgFilter) {
reject(rejectMessages.invalidParameters);
}
_this2._changeFilterValues(imgFilter, options);
_this2._apply(sourceImg, function () {
canvas.renderAll();
resolve({
type: type,
action: 'add'
});
});
});
}
/**
* Remove filter to source image
* @param {string} type - Filter type
* @returns {Promise}
*/
}, {
key: 'remove',
value: function remove(type) {
var _this3 = this;
return new _promise2.default(function (resolve, reject) {
var sourceImg = _this3._getSourceImage();
var canvas = _this3.getCanvas();
if (!sourceImg.filters.length) {
reject(rejectMessages.unsupportedOperation);
}
_this3._removeFilter(sourceImg, type);
_this3._apply(sourceImg, function () {
canvas.renderAll();
resolve({
type: type,
action: 'remove'
});
});
});
}
/**
* Whether this has the filter or not
* @param {string} type - Filter type
* @returns {boolean} true if it has the filter
*/
}, {
key: 'hasFilter',
value: function hasFilter(type) {
return !!this._getFilter(this._getSourceImage(), type);
}
/**
* Get a filter options
* @param {string} type - Filter type
* @returns {Object} filter options or null if there is no that filter
*/
}, {
key: 'getOptions',
value: function getOptions(type) {
var sourceImg = this._getSourceImage();
var imgFilter = this._getFilter(sourceImg, type);
if (!imgFilter) {
return null;
}
return (0, _tuiCodeSnippet.extend)({}, imgFilter.options);
}
/**
* Change filter values
* @param {Object} imgFilter object of filter
* @param {Object} options object
* @private
*/
}, {
key: '_changeFilterValues',
value: function _changeFilterValues(imgFilter, options) {
(0, _tuiCodeSnippet.forEach)(options, function (value, key) {
if (!(0, _tuiCodeSnippet.isUndefined)(imgFilter[key])) {
imgFilter[key] = value;
}
});
(0, _tuiCodeSnippet.forEach)(imgFilter.options, function (value, key) {
if (!(0, _tuiCodeSnippet.isUndefined)(options[key])) {
imgFilter.options[key] = options[key];
}
});
}
/**
* Apply filter
* @param {fabric.Image} sourceImg - Source image to apply filter
* @param {function} callback - Executed function after applying filter
* @private
*/
}, {
key: '_apply',
value: function _apply(sourceImg, callback) {
sourceImg.applyFilters(callback);
}
/**
* Get source image on canvas
* @returns {fabric.Image} Current source image on canvas
* @private
*/
}, {
key: '_getSourceImage',
value: function _getSourceImage() {
return this.getCanvasImage();
}
/**
* Create filter instance
* @param {fabric.Image} sourceImg - Source image to apply filter
* @param {string} type - Filter type
* @param {Object} [options] - Options of filter
* @returns {Object} Fabric object of filter
* @private
*/
}, {
key: '_createFilter',
value: function _createFilter(sourceImg, type, options) {
var filterObj = void 0;
// capitalize first letter for matching with fabric image filter name
var fabricType = this._getFabricFilterType(type);
var ImageFilter = _fabric2.default.Image.filters[fabricType];
if (ImageFilter) {
filterObj = new ImageFilter(options);
filterObj.options = options;
sourceImg.filters.push(filterObj);
}
return filterObj;
}
/**
* Get applied filter instance
* @param {fabric.Image} sourceImg - Source image to apply filter
* @param {string} type - Filter type
* @returns {Object} Fabric object of filter
* @private
*/
}, {
key: '_getFilter',
value: function _getFilter(sourceImg, type) {
var imgFilter = null;
if (sourceImg) {
var fabricType = this._getFabricFilterType(type);
var length = sourceImg.filters.length;
var item = void 0,
i = void 0;
for (i = 0; i < length; i += 1) {
item = sourceImg.filters[i];
if (item.type === fabricType) {
imgFilter = item;
break;
}
}
}
return imgFilter;
}
/**
* Remove applied filter instance
* @param {fabric.Image} sourceImg - Source image to apply filter
* @param {string} type - Filter type
* @private
*/
}, {
key: '_removeFilter',
value: function _removeFilter(sourceImg, type) {
var fabricType = this._getFabricFilterType(type);
sourceImg.filters = (0, _tuiCodeSnippet.filter)(sourceImg.filters, function (value) {
return value.type !== fabricType;
});
}
/**
* Change filter class name to fabric's, especially capitalizing first letter
* @param {string} type - Filter type
* @example
* 'grayscale' -> 'Grayscale'
* @returns {string} Fabric filter class name
*/
}, {
key: '_getFabricFilterType',
value: function _getFabricFilterType(type) {
return type.charAt(0).toUpperCase() + type.slice(1);
}
}]);
return Filter;
}(_component2.default);
module.exports = Filter;
/***/ }),
/* 161 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _fabric = __webpack_require__(105);
var _fabric2 = _interopRequireDefault(_fabric);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Mask object
* @class Mask
* @extends {fabric.Image.filters.Mask}
* @ignore
*/
var Mask = _fabric2.default.util.createClass(_fabric2.default.Image.filters.Mask, /** @lends Mask.prototype */{
/**
* Apply filter to canvas element
* @param {Object} canvasEl - Canvas element to apply filter
* @override
*/
applyTo: function applyTo(canvasEl) {
if (!this.mask) {
return;
}
var width = canvasEl.width,
height = canvasEl.height;
var maskCanvasEl = this._createCanvasOfMask(width, height);
var ctx = canvasEl.getContext('2d');
var maskCtx = maskCanvasEl.getContext('2d');
var imageData = ctx.getImageData(0, 0, width, height);
this._drawMask(maskCtx, canvasEl, ctx);
this._mapData(maskCtx, imageData, width, height);
ctx.putImageData(imageData, 0, 0);
},
/**
* Create canvas of mask image
* @param {number} width - Width of main canvas
* @param {number} height - Height of main canvas
* @returns {HTMLElement} Canvas element
* @private
*/
_createCanvasOfMask: function _createCanvasOfMask(width, height) {
var maskCanvasEl = _fabric2.default.util.createCanvasElement();
maskCanvasEl.width = width;
maskCanvasEl.height = height;
return maskCanvasEl;
},
/**
* Draw mask image on canvas element
* @param {Object} maskCtx - Context of mask canvas
* @private
*/
_drawMask: function _drawMask(maskCtx) {
var mask = this.mask;
var maskImg = mask.getElement();
var left = mask.getLeft();
var top = mask.getTop();
var angle = mask.getAngle();
maskCtx.save();
maskCtx.translate(left, top);
maskCtx.rotate(angle * Math.PI / 180);
maskCtx.scale(mask.scaleX, mask.scaleY);
maskCtx.drawImage(maskImg, -maskImg.width / 2, -maskImg.height / 2);
maskCtx.restore();
},
/**
* Map mask image data to source image data
* @param {Object} maskCtx - Context of mask canvas
* @param {Object} imageData - Data of source image
* @param {number} width - Width of main canvas
* @param {number} height - Height of main canvas
* @private
*/
_mapData: function _mapData(maskCtx, imageData, width, height) {
var sourceData = imageData.data;
var maskData = maskCtx.getImageData(0, 0, width, height).data;
var channel = this.channel;
var len = imageData.width * imageData.height * 4;
for (var i = 0; i < len; i += 4) {
sourceData[i + 3] = maskData[i + channel]; // adjust value of alpha data
}
}
}); /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Mask extending fabric.Image.filters.Mask
*/
module.exports = Mask;
/***/ }),
/* 162 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _fabric = __webpack_require__(105);
var _fabric2 = _interopRequireDefault(_fabric);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Blur object
* @class Blur
* @extends {fabric.Image.filters.Convolute}
* @ignore
*/
var Blur = _fabric2.default.util.createClass(_fabric2.default.Image.filters.Convolute, /** @lends Convolute.prototype */{
/**
* Filter type
* @param {String} type
* @default
*/
type: 'Blur',
/**
* constructor
* @override
*/
initialize: function initialize() {
var matrix = [1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9];
this.matrix = matrix;
}
}); /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Blur extending fabric.Image.filters.Convolute
*/
module.exports = Blur;
/***/ }),
/* 163 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _fabric = __webpack_require__(105);
var _fabric2 = _interopRequireDefault(_fabric);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Sharpen object
* @class Sharpen
* @extends {fabric.Image.filters.Convolute}
* @ignore
*/
var Sharpen = _fabric2.default.util.createClass(_fabric2.default.Image.filters.Convolute, /** @lends Convolute.prototype */{
/**
* Filter type
* @param {String} type
* @default
*/
type: 'Sharpen',
/**
* constructor
* @override
*/
initialize: function initialize() {
var matrix = [0, -1, 0, -1, 5, -1, 0, -1, 0];
this.matrix = matrix;
}
}); /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Sharpen extending fabric.Image.filters.Convolute
*/
module.exports = Sharpen;
/***/ }),
/* 164 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _fabric = __webpack_require__(105);
var _fabric2 = _interopRequireDefault(_fabric);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Emboss object
* @class Emboss
* @extends {fabric.Image.filters.Convolute}
* @ignore
*/
var Emboss = _fabric2.default.util.createClass(_fabric2.default.Image.filters.Convolute, /** @lends Convolute.prototype */{
/**
* Filter type
* @param {String} type
* @default
*/
type: 'Emboss',
/**
* constructor
* @override
*/
initialize: function initialize() {
var matrix = [1, 1, 1, 1, 0.7, -1, -1, -1, -1];
this.matrix = matrix;
}
}); /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Emboss extending fabric.Image.filters.Convolute
*/
module.exports = Emboss;
/***/ }),
/* 165 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _fabric = __webpack_require__(105);
var _fabric2 = _interopRequireDefault(_fabric);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* ColorFilter object
* @class ColorFilter
* @extends {fabric.Image.filters.BaseFilter}
* @ignore
*/
var ColorFilter = _fabric2.default.util.createClass(_fabric2.default.Image.filters.BaseFilter, /** @lends BaseFilter.prototype */{
/**
* Filter type
* @param {String} type
* @default
*/
type: 'ColorFilter',
/**
* Constructor
* @member fabric.Image.filters.ColorFilter.prototype
* @param {Object} [options] Options object
* @param {Number} [options.color='#FFFFFF'] Value of color (0...255)
* @param {Number} [options.threshold=45] Value of threshold (0...255)
* @override
*/
initialize: function initialize(options) {
if (!options) {
options = {};
}
this.color = options.color || '#FFFFFF';
this.threshold = options.threshold || 45;
this.x = options.x || null;
this.y = options.y || null;
},
/**
* Applies filter to canvas element
* @param {Object} canvasEl Canvas element to apply filter to
*/
applyTo: function applyTo(canvasEl) {
// eslint-disable-line
var context = canvasEl.getContext('2d');
var imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height);
var data = imageData.data;
var threshold = this.threshold;
var filterColor = _fabric2.default.Color.sourceFromHex(this.color);
var i = void 0,
len = void 0;
if (this.x && this.y) {
filterColor = this._getColor(imageData, this.x, this.y);
}
for (i = 0, len = data.length; i < len; i += 4) {
if (this._isOutsideThreshold(data[i], filterColor[0], threshold) || this._isOutsideThreshold(data[i + 1], filterColor[1], threshold) || this._isOutsideThreshold(data[i + 2], filterColor[2], threshold)) {
continue;
}
data[i] = data[i + 1] = data[i + 2] = data[i + 3] = 0;
}
context.putImageData(imageData, 0, 0);
},
/**
* Check color if it is within threshold
* @param {Number} color1 source color
* @param {Number} color2 filtering color
* @param {Number} threshold threshold
* @returns {boolean} true if within threshold or false
*/
_isOutsideThreshold: function _isOutsideThreshold(color1, color2, threshold) {
var diff = color1 - color2;
return Math.abs(diff) > threshold;
},
/**
* Get color at (x, y)
* @param {Object} imageData of canvas
* @param {Number} x left position
* @param {Number} y top position
* @returns {Array} color array
*/
_getColor: function _getColor(imageData, x, y) {
var color = [0, 0, 0, 0];
var data = imageData.data,
width = imageData.width;
var bytes = 4;
var position = (width * y + x) * bytes;
color[0] = data[position];
color[1] = data[position + 1];
color[2] = data[position + 2];
color[3] = data[position + 3];
return color;
}
}); /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview ColorFilter extending fabric.Image.filters.BaseFilter
*/
module.exports = ColorFilter;
/***/ }),
/* 166 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _fabric = __webpack_require__(105);
var _fabric2 = _interopRequireDefault(_fabric);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* OldMaker object
* @class OldMaker
* @extends {fabric.Image.filters.BaseFilter}
* @ignore
*/
var OldMaker = _fabric2.default.util.createClass(_fabric2.default.Image.filters.BaseFilter, /** @lends BaseFilter.prototype */{
/**
* Filter type
* @param {String} type
* @default
*/
type: 'OldMaker',
/**
* Constructor
* @member fabric.Image.filters.OldMaker.prototype
* @param {Object} [options] Options object
* @param {Number} [options.color='#FFFFFF'] Value of color (0...255)
* @param {Number} [options.threshold=45] Value of threshold (0...255)
* @override
*/
initialize: function initialize(options) {
if (!options) {
options = {};
}
this.percent = options.percent || 50;
},
/**
* Applies filter to canvas element
* @param {Object} canvasEl Canvas element to apply filter to
*/
applyTo: function applyTo(canvasEl) {
// eslint-disable-line
var context = canvasEl.getContext('2d');
var imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height);
var _imageData = imageData,
data = _imageData.data,
width = _imageData.width,
height = _imageData.height;
var area_min = width < height ? width : height;
// add noise
// add pixed
// add blur
var noiseBase = 15;
var PixedBase = 0.026 * Math.pow(area_min, 0.737); // 160 * 160 比较好的pixed=1, 之后的可以按照该公式变化
var BlurBase = 0.02;
var percent = this.percent / 100;
this._addNoise(data, Math.floor(noiseBase * percent));
this._addPixed(data, height, width, Math.floor(PixedBase * percent));
imageData = this._simpleBlur(context, imageData, percent * BlurBase);
context.putImageData(imageData, 0, 0);
},
/**
* noise filter
* @param data
* @param noise
* @private
*/
_addNoise: function _addNoise(data, noise) {
var rand = 0;
for (var i = 0, len = data.length; i < len; i += 4) {
rand = (0.5 - Math.random()) * noise;
data[i] += rand;
data[i + 1] += rand;
data[i + 2] += rand;
}
},
/**
* pixed filter
* @param data
* @param height
* @param width
* @param blockSize
* @private
*/
_addPixed: function _addPixed(data, height, width, blockSize) {
var r = void 0,
g = void 0,
b = void 0,
a = void 0,
_height = void 0,
_width = void 0;
blockSize *= 1;
if (blockSize <= 0) {
return;
}
for (var i = 0; i < height; i += blockSize) {
for (var j = 0; j < width; j += blockSize) {
var index = i * 4 * width + j * 4;
r = data[index];
g = data[index + 1];
b = data[index + 2];
a = data[index + 3];
_height = Math.min(i + blockSize, height);
_width = Math.min(j + blockSize, width);
for (var _i = i; _i < _height; _i += 1) {
for (var _j = j; _j < _width; _j += 1) {
index = _i * 4 * width + _j * 4;
data[index] = r;
data[index + 1] = g;
data[index + 2] = b;
data[index + 3] = a;
}
}
}
}
},
/**
* blur filter
* @param context
* @param imageData
* @param _blur
* @returns {ImageData}
* @private
*/
_simpleBlur: function _simpleBlur(context, imageData, _blur) {
var canvas1 = void 0,
canvas2 = void 0,
width = imageData.width,
height = imageData.height;
canvas1 = _fabric2.default.util.createCanvasElement();
canvas2 = _fabric2.default.util.createCanvasElement();
if (canvas1.width !== width || canvas1.height !== height) {
canvas2.width = canvas1.width = width;
canvas2.height = canvas1.height = height;
}
var ctx1 = canvas1.getContext('2d'),
ctx2 = canvas2.getContext('2d'),
nSamples = 15,
random = void 0,
percent = void 0,
j = void 0,
i = void 0,
blur = _blur * 0.06 * 0.5;
// load first canvas
ctx1.putImageData(imageData, 0, 0);
ctx2.clearRect(0, 0, width, height);
for (i = -nSamples; i <= nSamples; i++) {
//random = (Math.random() - 0.5) / 4;
percent = i / nSamples;
j = blur * percent * width + random;
ctx2.globalAlpha = 1 - Math.abs(percent);
ctx2.drawImage(canvas1, j, random);
ctx1.drawImage(canvas2, 0, 0);
ctx2.globalAlpha = 1;
ctx2.clearRect(0, 0, canvas2.width, canvas2.height);
}
for (i = -nSamples; i <= nSamples; i++) {
//random = (Math.random() - 0.5) / 4;
random = 0;
percent = i / nSamples;
j = blur * percent * height + random;
ctx2.globalAlpha = 1 - Math.abs(percent);
ctx2.drawImage(canvas1, random, j);
ctx1.drawImage(canvas2, 0, 0);
ctx2.globalAlpha = 1;
ctx2.clearRect(0, 0, canvas2.width, canvas2.height);
}
context.drawImage(canvas1, 0, 0);
var newImageData = context.getImageData(0, 0, canvas1.width, canvas1.height);
ctx1.globalAlpha = 1;
ctx1.clearRect(0, 0, canvas1.width, canvas1.height);
return newImageData;
}
}); /* eslint-disable */
/**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview ColorFilter extending fabric.Image.filters.BaseFilter
*/
module.exports = OldMaker;
/***/ }),
/* 167 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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 _fabric = __webpack_require__(105);
var _fabric2 = _interopRequireDefault(_fabric);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _component = __webpack_require__(151);
var _component2 = _interopRequireDefault(_component);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
var _shapeResizeHelper = __webpack_require__(168);
var _shapeResizeHelper2 = _interopRequireDefault(_shapeResizeHelper);
var _tuiCodeSnippet = __webpack_require__(3);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Shape component
*/
var rejectMessages = _consts2.default.rejectMessages,
eventNames = _consts2.default.eventNames;
var KEY_CODES = _consts2.default.keyCodes;
var DEFAULT_TYPE = 'rect';
var DEFAULT_OPTIONS = {
strokeWidth: 1,
stroke: '#000000',
fill: '#ffffff',
width: 1,
height: 1,
rx: 0,
ry: 0,
lockSkewingX: true,
lockSkewingY: true,
lockUniScaling: false,
bringForward: true,
isRegular: false
};
var shapeType = ['rect', 'circle', 'triangle'];
/**
* Shape
* @class Shape
* @param {Graphics} graphics - Graphics instance
* @extends {Component}
* @ignore
*/
var Shape = function (_Component) {
_inherits(Shape, _Component);
function Shape(graphics) {
_classCallCheck(this, Shape);
/**
* Object of The drawing shape
* @type {fabric.Object}
* @private
*/
var _this = _possibleConstructorReturn(this, (Shape.__proto__ || Object.getPrototypeOf(Shape)).call(this, _consts2.default.componentNames.SHAPE, graphics));
_this._shapeObj = null;
/**
* Type of the drawing shape
* @type {string}
* @private
*/
_this._type = DEFAULT_TYPE;
/**
* Options to draw the shape
* @type {Object}
* @private
*/
_this._options = (0, _tuiCodeSnippet.extend)({}, DEFAULT_OPTIONS);
/**
* Whether the shape object is selected or not
* @type {boolean}
* @private
*/
_this._isSelected = false;
/**
* Pointer for drawing shape (x, y)
* @type {Object}
* @private
*/
_this._startPoint = {};
/**
* Using shortcut on drawing shape
* @type {boolean}
* @private
*/
_this._withShiftKey = false;
/**
* Event handler list
* @type {Object}
* @private
*/
_this._handlers = {
mousedown: _this._onFabricMouseDown.bind(_this),
mousemove: _this._onFabricMouseMove.bind(_this),
mouseup: _this._onFabricMouseUp.bind(_this),
keydown: _this._onKeyDown.bind(_this),
keyup: _this._onKeyUp.bind(_this)
};
return _this;
}
/**
* Start to draw the shape on canvas
* @ignore
*/
_createClass(Shape, [{
key: 'start',
value: function start() {
var canvas = this.getCanvas();
this._isSelected = false;
canvas.defaultCursor = 'crosshair';
canvas.selection = false;
canvas.uniScaleTransform = true;
canvas.on({
'mouse:down': this._handlers.mousedown
});
_fabric2.default.util.addListener(document, 'keydown', this._handlers.keydown);
_fabric2.default.util.addListener(document, 'keyup', this._handlers.keyup);
}
/**
* End to draw the shape on canvas
* @ignore
*/
}, {
key: 'end',
value: function end() {
var canvas = this.getCanvas();
this._isSelected = false;
canvas.defaultCursor = 'default';
canvas.selection = true;
canvas.uniScaleTransform = false;
canvas.off({
'mouse:down': this._handlers.mousedown
});
_fabric2.default.util.removeListener(document, 'keydown', this._handlers.keydown);
_fabric2.default.util.removeListener(document, 'keyup', this._handlers.keyup);
}
/**
* Set states of the current drawing shape
* @ignore
* @param {string} type - Shape type (ex: 'rect', 'circle')
* @param {Object} [options] - Shape options
* @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
* @param {string} [options.stoke] - Shape outline color
* @param {number} [options.strokeWidth] - Shape outline width
* @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
* @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
* @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
* @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
*/
}, {
key: 'setStates',
value: function setStates(type, options) {
this._type = type;
if (options) {
this._options = (0, _tuiCodeSnippet.extend)(this._options, options);
}
}
/**
* Add the shape
* @ignore
* @param {string} type - Shape type (ex: 'rect', 'circle')
* @param {Object} options - Shape options
* @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
* @param {string} [options.stroke] - Shape outline color
* @param {number} [options.strokeWidth] - Shape outline width
* @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
* @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
* @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
* @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
* @param {number} [options.isRegular] - Whether scaling shape has 1:1 ratio or not
* @returns {Promise}
*/
}, {
key: 'add',
value: function add(type, options) {
var _this2 = this;
return new _promise2.default(function (resolve) {
var canvas = _this2.getCanvas();
options = _this2._createOptions(options);
var shapeObj = _this2._createInstance(type, options);
_this2._bindEventOnShape(shapeObj);
canvas.add(shapeObj).setActiveObject(shapeObj);
resolve(_this2.graphics.createObjectProperties(shapeObj));
});
}
/**
* Change the shape
* @ignore
* @param {fabric.Object} shapeObj - Selected shape object on canvas
* @param {Object} options - Shape options
* @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
* @param {string} [options.stroke] - Shape outline color
* @param {number} [options.strokeWidth] - Shape outline width
* @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
* @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
* @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
* @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
* @param {number} [options.isRegular] - Whether scaling shape has 1:1 ratio or not
* @returns {Promise}
*/
}, {
key: 'change',
value: function change(shapeObj, options) {
var _this3 = this;
return new _promise2.default(function (resolve, reject) {
if ((0, _tuiCodeSnippet.inArray)(shapeObj.get('type'), shapeType) < 0) {
reject(rejectMessages.unsupportedType);
}
shapeObj.set(options);
_this3.getCanvas().renderAll();
resolve();
});
}
/**
* Create the instance of shape
* @param {string} type - Shape type
* @param {Object} options - Options to creat the shape
* @returns {fabric.Object} Shape instance
* @private
*/
}, {
key: '_createInstance',
value: function _createInstance(type, options) {
var instance = void 0;
switch (type) {
case 'rect':
instance = new _fabric2.default.Rect(options);
break;
case 'circle':
instance = new _fabric2.default.Ellipse((0, _tuiCodeSnippet.extend)({
type: 'circle'
}, options));
break;
case 'triangle':
instance = new _fabric2.default.Triangle(options);
break;
default:
instance = {};
}
return instance;
}
/**
* Get the options to create the shape
* @param {Object} options - Options to creat the shape
* @returns {Object} Shape options
* @private
*/
}, {
key: '_createOptions',
value: function _createOptions(options) {
var selectionStyles = _consts2.default.fObjectOptions.SELECTION_STYLE;
options = (0, _tuiCodeSnippet.extend)({}, DEFAULT_OPTIONS, this._options, selectionStyles, options);
if (options.isRegular) {
options.lockUniScaling = true;
}
return options;
}
/**
* Bind fabric events on the creating shape object
* @param {fabric.Object} shapeObj - Shape object
* @private
*/
}, {
key: '_bindEventOnShape',
value: function _bindEventOnShape(shapeObj) {
var self = this;
var canvas = this.getCanvas();
shapeObj.on({
added: function added() {
self._shapeObj = this;
_shapeResizeHelper2.default.setOrigins(self._shapeObj);
},
selected: function selected() {
self._isSelected = true;
self._shapeObj = this;
canvas.uniScaleTransform = true;
canvas.defaultCursor = 'default';
_shapeResizeHelper2.default.setOrigins(self._shapeObj);
},
deselected: function deselected() {
self._isSelected = false;
self._shapeObj = null;
canvas.defaultCursor = 'crosshair';
canvas.uniScaleTransform = false;
},
modified: function modified() {
var currentObj = self._shapeObj;
_shapeResizeHelper2.default.adjustOriginToCenter(currentObj);
_shapeResizeHelper2.default.setOrigins(currentObj);
},
scaling: function scaling(fEvent) {
var pointer = canvas.getPointer(fEvent.e);
var currentObj = self._shapeObj;
canvas.setCursor('crosshair');
_shapeResizeHelper2.default.resize(currentObj, pointer, true);
}
});
}
/**
* MouseDown event handler on canvas
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object
* @private
*/
}, {
key: '_onFabricMouseDown',
value: function _onFabricMouseDown(fEvent) {
if (!fEvent.target) {
this._isSelected = false;
this._shapeObj = false;
}
if (!this._isSelected && !this._shapeObj) {
var canvas = this.getCanvas();
this._startPoint = canvas.getPointer(fEvent.e);
canvas.on({
'mouse:move': this._handlers.mousemove,
'mouse:up': this._handlers.mouseup
});
}
}
/**
* MouseDown event handler on canvas
* @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object
* @private
*/
}, {
key: '_onFabricMouseMove',
value: function _onFabricMouseMove(fEvent) {
var _this4 = this;
var canvas = this.getCanvas();
var pointer = canvas.getPointer(fEvent.e);
var startPointX = this._startPoint.x;
var startPointY = this._startPoint.y;
var width = startPointX - pointer.x;
var height = startPointY - pointer.y;
var shape = this._shapeObj;
if (!shape) {
this.add(this._type, {
left: startPointX,
top: startPointY,
width: width,
height: height
}).then(function (objectProps) {
_this4.fire(eventNames.ADD_OBJECT, objectProps);
});
} else {
this._shapeObj.set({
isRegular: this._withShiftKey
});
_shapeResizeHelper2.default.resize(shape, pointer);
canvas.renderAll();
}
}
/**
* MouseUp event handler on canvas
* @private
*/
}, {
key: '_onFabricMouseUp',
value: function _onFabricMouseUp() {
var canvas = this.getCanvas();
var shape = this._shapeObj;
if (shape) {
_shapeResizeHelper2.default.adjustOriginToCenter(shape);
}
this.fire(eventNames.ADD_OBJECT_AFTER, this.graphics.createObjectProperties(shape));
canvas.off({
'mouse:move': this._handlers.mousemove,
'mouse:up': this._handlers.mouseup
});
}
/**
* Keydown event handler on document
* @param {KeyboardEvent} e - Event object
* @private
*/
}, {
key: '_onKeyDown',
value: function _onKeyDown(e) {
if (e.keyCode === KEY_CODES.SHIFT) {
this._withShiftKey = true;
if (this._shapeObj) {
this._shapeObj.isRegular = true;
}
}
}
/**
* Keyup event handler on document
* @param {KeyboardEvent} e - Event object
* @private
*/
}, {
key: '_onKeyUp',
value: function _onKeyUp(e) {
if (e.keyCode === KEY_CODES.SHIFT) {
this._withShiftKey = false;
if (this._shapeObj) {
this._shapeObj.isRegular = false;
}
}
}
}]);
return Shape;
}(_component2.default);
module.exports = Shape;
/***/ }),
/* 168 */
/***/ (function(module, exports) {
'use strict';
/**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Shape resize helper
*/
var DIVISOR = {
rect: 1,
circle: 2,
triangle: 1
};
var DIMENSION_KEYS = {
rect: {
w: 'width',
h: 'height'
},
circle: {
w: 'rx',
h: 'ry'
},
triangle: {
w: 'width',
h: 'height'
}
};
/**
* Set the start point value to the shape object
* @param {fabric.Object} shape - Shape object
* @ignore
*/
function setStartPoint(shape) {
var originX = shape.getOriginX();
var originY = shape.getOriginY();
var originKey = originX.substring(0, 1) + originY.substring(0, 1);
shape.startPoint = shape.origins[originKey];
}
/**
* Get the positions of ratated origin by the pointer value
* @param {{x: number, y: number}} origin - Origin value
* @param {{x: number, y: number}} pointer - Pointer value
* @param {number} angle - Rotating angle
* @returns {Object} Postions of origin
* @ignore
*/
function getPositionsOfRotatedOrigin(origin, pointer, angle) {
var sx = origin.x;
var sy = origin.y;
var px = pointer.x;
var py = pointer.y;
var r = angle * Math.PI / 180;
var rx = (px - sx) * Math.cos(r) - (py - sy) * Math.sin(r) + sx;
var ry = (px - sx) * Math.sin(r) + (py - sy) * Math.cos(r) + sy;
return {
originX: sx > rx ? 'right' : 'left',
originY: sy > ry ? 'bottom' : 'top'
};
}
/**
* Whether the shape has the center origin or not
* @param {fabric.Object} shape - Shape object
* @returns {boolean} State
* @ignore
*/
function hasCenterOrigin(shape) {
return shape.getOriginX() === 'center' && shape.getOriginY() === 'center';
}
/**
* Adjust the origin of shape by the start point
* @param {{x: number, y: number}} pointer - Pointer value
* @param {fabric.Object} shape - Shape object
* @ignore
*/
function adjustOriginByStartPoint(pointer, shape) {
var centerPoint = shape.getPointByOrigin('center', 'center');
var angle = -shape.getAngle();
var originPositions = getPositionsOfRotatedOrigin(centerPoint, pointer, angle);
var originX = originPositions.originX,
originY = originPositions.originY;
var origin = shape.getPointByOrigin(originX, originY);
var left = shape.getLeft() - (centerPoint.x - origin.x);
var top = shape.getTop() - (centerPoint.x - origin.y);
shape.set({
originX: originX,
originY: originY,
left: left,
top: top
});
shape.setCoords();
}
/**
* Adjust the origin of shape by the moving pointer value
* @param {{x: number, y: number}} pointer - Pointer value
* @param {fabric.Object} shape - Shape object
* @ignore
*/
function adjustOriginByMovingPointer(pointer, shape) {
var origin = shape.startPoint;
var angle = -shape.getAngle();
var originPositions = getPositionsOfRotatedOrigin(origin, pointer, angle);
var originX = originPositions.originX,
originY = originPositions.originY;
shape.setPositionByOrigin(origin, originX, originY);
}
/**
* Adjust the dimension of shape on firing scaling event
* @param {fabric.Object} shape - Shape object
* @ignore
*/
function adjustDimensionOnScaling(shape) {
var type = shape.type,
scaleX = shape.scaleX,
scaleY = shape.scaleY;
var dimensionKeys = DIMENSION_KEYS[type];
var width = shape[dimensionKeys.w] * scaleX;
var height = shape[dimensionKeys.h] * scaleY;
if (shape.isRegular) {
var maxScale = Math.max(scaleX, scaleY);
width = shape[dimensionKeys.w] * maxScale;
height = shape[dimensionKeys.h] * maxScale;
}
var options = {
hasControls: false,
hasBorders: false,
scaleX: 1,
scaleY: 1
};
options[dimensionKeys.w] = width;
options[dimensionKeys.h] = height;
shape.set(options);
}
/**
* Adjust the dimension of shape on firing mouse move event
* @param {{x: number, y: number}} pointer - Pointer value
* @param {fabric.Object} shape - Shape object
* @ignore
*/
function adjustDimensionOnMouseMove(pointer, shape) {
var type = shape.type,
strokeWidth = shape.strokeWidth,
origin = shape.startPoint;
var divisor = DIVISOR[type];
var dimensionKeys = DIMENSION_KEYS[type];
var isTriangle = !!(shape.type === 'triangle');
var options = {};
var width = Math.abs(origin.x - pointer.x) / divisor;
var height = Math.abs(origin.y - pointer.y) / divisor;
if (width > strokeWidth) {
width -= strokeWidth / divisor;
}
if (height > strokeWidth) {
height -= strokeWidth / divisor;
}
if (shape.isRegular) {
width = height = Math.max(width, height);
if (isTriangle) {
height = Math.sqrt(3) / 2 * width;
}
}
options[dimensionKeys.w] = width;
options[dimensionKeys.h] = height;
shape.set(options);
}
module.exports = {
/**
* Set each origin value to shape
* @param {fabric.Object} shape - Shape object
*/
setOrigins: function setOrigins(shape) {
var leftTopPoint = shape.getPointByOrigin('left', 'top');
var rightTopPoint = shape.getPointByOrigin('right', 'top');
var rightBottomPoint = shape.getPointByOrigin('right', 'bottom');
var leftBottomPoint = shape.getPointByOrigin('left', 'bottom');
shape.origins = {
lt: leftTopPoint,
rt: rightTopPoint,
rb: rightBottomPoint,
lb: leftBottomPoint
};
},
/**
* Resize the shape
* @param {fabric.Object} shape - Shape object
* @param {{x: number, y: number}} pointer - Mouse pointer values on canvas
* @param {boolean} isScaling - Whether the resizing action is scaling or not
*/
resize: function resize(shape, pointer, isScaling) {
if (hasCenterOrigin(shape)) {
adjustOriginByStartPoint(pointer, shape);
setStartPoint(shape);
}
if (isScaling) {
adjustDimensionOnScaling(shape, pointer);
} else {
adjustDimensionOnMouseMove(pointer, shape);
}
adjustOriginByMovingPointer(pointer, shape);
},
/**
* Adjust the origin position of shape to center
* @param {fabric.Object} shape - Shape object
*/
adjustOriginToCenter: function adjustOriginToCenter(shape) {
var centerPoint = shape.getPointByOrigin('center', 'center');
var originX = shape.getOriginX();
var originY = shape.getOriginY();
var origin = shape.getPointByOrigin(originX, originY);
var left = shape.getLeft() + (centerPoint.x - origin.x);
var top = shape.getTop() + (centerPoint.y - origin.y);
shape.set({
hasControls: true,
hasBorders: true,
originX: 'center',
originY: 'center',
left: left,
top: top
});
shape.setCoords(); // For left, top properties
}
};
/***/ }),
/* 169 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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 _drawingMode = __webpack_require__(170);
var _drawingMode2 = _interopRequireDefault(_drawingMode);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview CropperDrawingMode class
*/
var drawingModes = _consts2.default.drawingModes;
var components = _consts2.default.componentNames;
/**
* CropperDrawingMode class
* @class
* @ignore
*/
var CropperDrawingMode = function (_DrawingMode) {
_inherits(CropperDrawingMode, _DrawingMode);
function CropperDrawingMode() {
_classCallCheck(this, CropperDrawingMode);
return _possibleConstructorReturn(this, (CropperDrawingMode.__proto__ || Object.getPrototypeOf(CropperDrawingMode)).call(this, drawingModes.CROPPER));
}
/**
* start this drawing mode
* @param {Graphics} graphics - Graphics instance
* @param {Object} options - Params options
* @override
*/
_createClass(CropperDrawingMode, [{
key: 'start',
value: function start(graphics, options) {
var cropper = graphics.getComponent(components.CROPPER);
cropper.start(options);
}
/**
* stop this drawing mode
* @param {Graphics} graphics - Graphics instance
* @override
*/
}, {
key: 'end',
value: function end(graphics) {
var cropper = graphics.getComponent(components.CROPPER);
cropper.end();
}
}]);
return CropperDrawingMode;
}(_drawingMode2.default);
module.exports = CropperDrawingMode;
/***/ }),
/* 170 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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; }; }(); /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview DrawingMode interface
*/
var _errorMessage = __webpack_require__(71);
var _errorMessage2 = _interopRequireDefault(_errorMessage);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var createMessage = _errorMessage2.default.create;
var errorTypes = _errorMessage2.default.types;
/**
* DrawingMode interface
* @class
* @param {string} name - drawing mode name
* @ignore
*/
var DrawingMode = function () {
function DrawingMode(name) {
_classCallCheck(this, DrawingMode);
/**
* the name of drawing mode
* @type {string}
*/
this.name = name;
}
/**
* Get this drawing mode name;
* @returns {string} drawing mode name
*/
_createClass(DrawingMode, [{
key: 'getName',
value: function getName() {
return this.name;
}
/**
* start this drawing mode
* @param {Object} options - drawing mode options
* @abstract
*/
}, {
key: 'start',
value: function start() {
throw new Error(createMessage(errorTypes.UN_IMPLEMENTATION, 'start'));
}
/**
* stop this drawing mode
* @abstract
*/
}, {
key: 'stop',
value: function stop() {
throw new Error(createMessage(errorTypes.UN_IMPLEMENTATION, 'stop'));
}
}]);
return DrawingMode;
}();
module.exports = DrawingMode;
/***/ }),
/* 171 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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 _drawingMode = __webpack_require__(170);
var _drawingMode2 = _interopRequireDefault(_drawingMode);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview FreeDrawingMode class
*/
var drawingModes = _consts2.default.drawingModes;
var components = _consts2.default.componentNames;
/**
* FreeDrawingMode class
* @class
* @ignore
*/
var FreeDrawingMode = function (_DrawingMode) {
_inherits(FreeDrawingMode, _DrawingMode);
function FreeDrawingMode() {
_classCallCheck(this, FreeDrawingMode);
return _possibleConstructorReturn(this, (FreeDrawingMode.__proto__ || Object.getPrototypeOf(FreeDrawingMode)).call(this, drawingModes.FREE_DRAWING));
}
/**
* start this drawing mode
* @param {Graphics} graphics - Graphics instance
* @param {{width: ?number, color: ?string}} [options] - Brush width & color
* @override
*/
_createClass(FreeDrawingMode, [{
key: 'start',
value: function start(graphics, options) {
var freeDrawing = graphics.getComponent(components.FREE_DRAWING);
freeDrawing.start(options);
}
/**
* stop this drawing mode
* @param {Graphics} graphics - Graphics instance
* @override
*/
}, {
key: 'end',
value: function end(graphics) {
var freeDrawing = graphics.getComponent(components.FREE_DRAWING);
freeDrawing.end();
}
}]);
return FreeDrawingMode;
}(_drawingMode2.default);
module.exports = FreeDrawingMode;
/***/ }),
/* 172 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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 _drawingMode = __webpack_require__(170);
var _drawingMode2 = _interopRequireDefault(_drawingMode);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview LineDrawingMode class
*/
var drawingModes = _consts2.default.drawingModes;
var components = _consts2.default.componentNames;
/**
* LineDrawingMode class
* @class
* @ignore
*/
var LineDrawingMode = function (_DrawingMode) {
_inherits(LineDrawingMode, _DrawingMode);
function LineDrawingMode() {
_classCallCheck(this, LineDrawingMode);
return _possibleConstructorReturn(this, (LineDrawingMode.__proto__ || Object.getPrototypeOf(LineDrawingMode)).call(this, drawingModes.LINE_DRAWING));
}
/**
* start this drawing mode
* @param {Graphics} graphics - Graphics instance
* @param {{width: ?number, color: ?string}} [options] - Brush width & color
* @override
*/
_createClass(LineDrawingMode, [{
key: 'start',
value: function start(graphics, options) {
var lineDrawing = graphics.getComponent(components.LINE);
lineDrawing.start(options);
}
/**
* stop this drawing mode
* @param {Graphics} graphics - Graphics instance
* @override
*/
}, {
key: 'end',
value: function end(graphics) {
var lineDrawing = graphics.getComponent(components.LINE);
lineDrawing.end();
}
}]);
return LineDrawingMode;
}(_drawingMode2.default);
module.exports = LineDrawingMode;
/***/ }),
/* 173 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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 _drawingMode = __webpack_require__(170);
var _drawingMode2 = _interopRequireDefault(_drawingMode);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview ShapeDrawingMode class
*/
var drawingModes = _consts2.default.drawingModes;
var components = _consts2.default.componentNames;
/**
* ShapeDrawingMode class
* @class
* @ignore
*/
var ShapeDrawingMode = function (_DrawingMode) {
_inherits(ShapeDrawingMode, _DrawingMode);
function ShapeDrawingMode() {
_classCallCheck(this, ShapeDrawingMode);
return _possibleConstructorReturn(this, (ShapeDrawingMode.__proto__ || Object.getPrototypeOf(ShapeDrawingMode)).call(this, drawingModes.SHAPE));
}
/**
* start this drawing mode
* @param {Graphics} graphics - Graphics instance
* @override
*/
_createClass(ShapeDrawingMode, [{
key: 'start',
value: function start(graphics) {
var shape = graphics.getComponent(components.SHAPE);
shape.start();
}
/**
* stop this drawing mode
* @param {Graphics} graphics - Graphics instance
* @override
*/
}, {
key: 'end',
value: function end(graphics) {
var shape = graphics.getComponent(components.SHAPE);
shape.end();
}
}]);
return ShapeDrawingMode;
}(_drawingMode2.default);
module.exports = ShapeDrawingMode;
/***/ }),
/* 174 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
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 _drawingMode = __webpack_require__(170);
var _drawingMode2 = _interopRequireDefault(_drawingMode);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview TextDrawingMode class
*/
var drawingModes = _consts2.default.drawingModes;
var components = _consts2.default.componentNames;
/**
* TextDrawingMode class
* @class
* @ignore
*/
var TextDrawingMode = function (_DrawingMode) {
_inherits(TextDrawingMode, _DrawingMode);
function TextDrawingMode() {
_classCallCheck(this, TextDrawingMode);
return _possibleConstructorReturn(this, (TextDrawingMode.__proto__ || Object.getPrototypeOf(TextDrawingMode)).call(this, drawingModes.TEXT));
}
/**
* start this drawing mode
* @param {Graphics} graphics - Graphics instance
* @override
*/
_createClass(TextDrawingMode, [{
key: 'start',
value: function start(graphics) {
var text = graphics.getComponent(components.TEXT);
text.start();
}
/**
* stop this drawing mode
* @param {Graphics} graphics - Graphics instance
* @override
*/
}, {
key: 'end',
value: function end(graphics) {
var text = graphics.getComponent(components.TEXT);
text.end();
}
}]);
return TextDrawingMode;
}(_drawingMode2.default);
module.exports = TextDrawingMode;
/***/ }),
/* 175 */
/***/ (function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ }),
/* 176 */,
/* 177 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var componentNames = _consts2.default.componentNames,
commandNames = _consts2.default.commandNames; /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Add an icon
*/
var ICON = componentNames.ICON;
var command = {
name: commandNames.ADD_ICON,
/**
* Add an icon
* @param {Graphics} graphics - Graphics instance
* @param {string} type - Icon type ('arrow', 'cancel', custom icon name)
* @param {Object} options - Icon options
* @param {string} [options.fill] - Icon foreground color
* @param {string} [options.left] - Icon x position
* @param {string} [options.top] - Icon y position
* @returns {Promise}
*/
execute: function execute(graphics, type, options) {
var _this = this;
var iconComp = graphics.getComponent(ICON);
return iconComp.add(type, options).then(function (objectProps) {
_this.undoData.object = graphics.getObject(objectProps.id);
return objectProps;
});
},
/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
undo: function undo(graphics) {
graphics.remove(this.undoData.object);
return _promise2.default.resolve();
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 178 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var commandNames = _consts2.default.commandNames; /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Add an image object
*/
var command = {
name: commandNames.ADD_IMAGE_OBJECT,
/**
* Add an image object
* @param {Graphics} graphics - Graphics instance
* @param {string} imgUrl - Image url to make object
* @returns {Promise}
*/
execute: function execute(graphics, imgUrl) {
var _this = this;
return graphics.addImageObject(imgUrl).then(function (objectProps) {
_this.undoData.object = graphics.getObject(objectProps.id);
return objectProps;
});
},
/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
undo: function undo(graphics) {
graphics.remove(this.undoData.object);
return _promise2.default.resolve();
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 179 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var commandNames = _consts2.default.commandNames,
rejectMessages = _consts2.default.rejectMessages; /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Add an object
*/
var command = {
name: commandNames.ADD_OBJECT,
/**
* Add an object
* @param {Graphics} graphics - Graphics instance
* @param {Object} object - Fabric object
* @returns {Promise}
*/
execute: function execute(graphics, object) {
return new _promise2.default(function (resolve, reject) {
if (!graphics.contains(object)) {
graphics.add(object);
resolve(object);
} else {
reject(rejectMessages.addedObject);
}
});
},
/**
* @param {Graphics} graphics - Graphics instance
* @param {Object} object - Fabric object
* @returns {Promise}
*/
undo: function undo(graphics, object) {
return new _promise2.default(function (resolve, reject) {
if (graphics.contains(object)) {
graphics.remove(object);
resolve(object);
} else {
reject(rejectMessages.noObject);
}
});
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 180 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var componentNames = _consts2.default.componentNames,
commandNames = _consts2.default.commandNames; /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Add a shape
*/
var SHAPE = componentNames.SHAPE;
var command = {
name: commandNames.ADD_SHAPE,
/**
* Add a shape
* @param {Graphics} graphics - Graphics instance
* @param {string} type - Shape type (ex: 'rect', 'circle', 'triangle')
* @param {Object} options - Shape options
* @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
* @param {string} [options.stroke] - Shape outline color
* @param {number} [options.strokeWidth] - Shape outline width
* @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
* @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
* @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
* @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
* @param {number} [options.left] - Shape x position
* @param {number} [options.top] - Shape y position
* @param {number} [options.isRegular] - Whether resizing shape has 1:1 ratio or not
* @returns {Promise}
*/
execute: function execute(graphics, type, options) {
var _this = this;
var shapeComp = graphics.getComponent(SHAPE);
return shapeComp.add(type, options).then(function (objectProps) {
_this.undoData.object = graphics.getObject(objectProps.id);
return objectProps;
});
},
/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
undo: function undo(graphics) {
graphics.remove(this.undoData.object);
return _promise2.default.resolve();
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 181 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var componentNames = _consts2.default.componentNames,
commandNames = _consts2.default.commandNames; /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Add a text object
*/
var TEXT = componentNames.TEXT;
var command = {
name: commandNames.ADD_TEXT,
/**
* Add a text object
* @param {Graphics} graphics - Graphics instance
* @param {string} text - Initial input text
* @param {Object} [options] Options for text styles
* @param {Object} [options.styles] Initial styles
* @param {string} [options.styles.fill] Color
* @param {string} [options.styles.fontFamily] Font type for text
* @param {number} [options.styles.fontSize] Size
* @param {string} [options.styles.fontStyle] Type of inclination (normal / italic)
* @param {string} [options.styles.fontWeight] Type of thicker or thinner looking (normal / bold)
* @param {string} [options.styles.textAlign] Type of text align (left / center / right)
* @param {string} [options.styles.textDecoraiton] Type of line (underline / line-throgh / overline)
* @param {{x: number, y: number}} [options.position] - Initial position
* @returns {Promise}
*/
execute: function execute(graphics, text, options) {
var _this = this;
var textComp = graphics.getComponent(TEXT);
return textComp.add(text, options).then(function (objectProps) {
_this.undoData.object = graphics.getObject(objectProps.id);
return objectProps;
});
},
/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
undo: function undo(graphics) {
graphics.remove(this.undoData.object);
return _promise2.default.resolve();
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 182 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var componentNames = _consts2.default.componentNames,
commandNames = _consts2.default.commandNames; /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Add a text object
*/
var TEXT = componentNames.TEXT;
var command = {
name: commandNames.ADD_TEXTS,
/**
* Add a text object
* @param {Graphics} graphics - Graphics instance
* @param {Array<config>} configs - Options for text and styles
* @param {String} config.text - text string
* @param {Object} [config.styles] Initial styles
* @param {string} [config.styles.fill] Color
* @param {string} [config.styles.fontFamily] Font type for text
* @param {number} [config.styles.fontSize] Size
* @param {string} [config.styles.fontStyle] Type of inclination (normal / italic)
* @param {string} [config.styles.fontWeight] Type of thicker or thinner looking (normal / bold)
* @param {string} [config.styles.textAlign] Type of text align (left / center / right)
* @param {string} [config.styles.textDecoraiton] Type of line (underline / line-throgh / overline)
* @param {{x: number, y: number}} [config.position] - Initial position
* @returns {Promise}
*/
execute: function execute(graphics, configs) {
var _this = this;
var textComp = graphics.getComponent(TEXT);
var result = [];
var config = null;
var p = null;
this.undoData.objectArray = [];
for (var index = 0; index < configs.length; index += 1) {
config = configs[index];
p = textComp.add(config.text, config.options).then(function (objectProps) {
_this.undoData.objectArray.push(graphics.getObject(objectProps.id));
return objectProps;
});
result.push(p);
}
return _promise2.default.all(result).then(function (arr) {
return arr;
});
},
/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
undo: function undo(graphics) {
for (var index = 0; index < this.undoData.objectArray.length; index += 1) {
graphics.remove(this.undoData.objectArray[index]);
}
return _promise2.default.resolve();
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 183 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Apply a filter into an image
*/
var componentNames = _consts2.default.componentNames,
rejectMessages = _consts2.default.rejectMessages,
commandNames = _consts2.default.commandNames;
var FILTER = componentNames.FILTER;
var command = {
name: commandNames.APPLY_FILTER,
/**
* Apply a filter into an image
* @param {Graphics} graphics - Graphics instance
* @param {string} type - Filter type
* @param {Object} options - Filter options
* @param {number} options.maskObjId - masking image object id
* @returns {Promise}
*/
execute: function execute(graphics, type, options) {
var filterComp = graphics.getComponent(FILTER);
if (type === 'mask') {
var maskObj = graphics.getObject(options.maskObjId);
if (!(maskObj && maskObj.isType('image'))) {
return Promise.reject(rejectMessages.invalidParameters);
}
options = {
mask: maskObj
};
}
if (type === 'mask') {
this.undoData.object = options.mask;
graphics.remove(options.mask);
} else {
this.undoData.options = filterComp.getOptions(type);
}
return filterComp.add(type, options);
},
/**
* @param {Graphics} graphics - Graphics instance
* @param {string} type - Filter type
* @returns {Promise}
*/
undo: function undo(graphics, type) {
var filterComp = graphics.getComponent(FILTER);
if (type === 'mask') {
var mask = this.undoData.object;
graphics.add(mask);
graphics.setActiveObject(mask);
return filterComp.remove(type);
}
// options changed case
if (this.undoData.options) {
return filterComp.add(type, this.undoData.options);
}
// filter added case
return filterComp.remove(type);
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 184 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var componentNames = _consts2.default.componentNames,
rejectMessages = _consts2.default.rejectMessages,
commandNames = _consts2.default.commandNames; /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Change icon color
*/
var ICON = componentNames.ICON;
var command = {
name: commandNames.CHANGE_ICON_COLOR,
/**
* Change icon color
* @param {Graphics} graphics - Graphics instance
* @param {number} id - object id
* @param {string} color - Color for icon
* @returns {Promise}
*/
execute: function execute(graphics, id, color) {
var _this = this;
return new _promise2.default(function (resolve, reject) {
var iconComp = graphics.getComponent(ICON);
var targetObj = graphics.getObject(id);
if (!targetObj) {
reject(rejectMessages.noObject);
}
_this.undoData.object = targetObj;
_this.undoData.color = iconComp.getColor(targetObj);
iconComp.setColor(color, targetObj);
resolve();
});
},
/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
undo: function undo(graphics) {
var iconComp = graphics.getComponent(ICON);
var _undoData$object = this.undoData.object,
icon = _undoData$object.object,
color = _undoData$object.color;
iconComp.setColor(color, icon);
return _promise2.default.resolve();
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 185 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _tuiCodeSnippet = __webpack_require__(3);
var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet);
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview change a shape
*/
var componentNames = _consts2.default.componentNames,
rejectMessages = _consts2.default.rejectMessages,
commandNames = _consts2.default.commandNames;
var SHAPE = componentNames.SHAPE;
var command = {
name: commandNames.CHANGE_SHAPE,
/**
* Change a shape
* @param {Graphics} graphics - Graphics instance
* @param {number} id - object id
* @param {Object} options - Shape options
* @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
* @param {string} [options.stroke] - Shape outline color
* @param {number} [options.strokeWidth] - Shape outline width
* @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
* @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
* @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
* @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
* @param {number} [options.left] - Shape x position
* @param {number} [options.top] - Shape y position
* @param {number} [options.isRegular] - Whether resizing shape has 1:1 ratio or not
* @returns {Promise}
*/
execute: function execute(graphics, id, options) {
var _this = this;
var shapeComp = graphics.getComponent(SHAPE);
var targetObj = graphics.getObject(id);
if (!targetObj) {
return _promise2.default.reject(rejectMessages.noObject);
}
this.undoData.object = targetObj;
this.undoData.options = {};
_tuiCodeSnippet2.default.forEachOwnProperties(options, function (value, key) {
_this.undoData.options[key] = targetObj[key];
});
return shapeComp.change(targetObj, options);
},
/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
undo: function undo(graphics) {
var shapeComp = graphics.getComponent(SHAPE);
var _undoData = this.undoData,
shape = _undoData.object,
options = _undoData.options;
return shapeComp.change(shape, options);
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 186 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var componentNames = _consts2.default.componentNames,
rejectMessages = _consts2.default.rejectMessages,
commandNames = _consts2.default.commandNames; /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Change a text
*/
var TEXT = componentNames.TEXT;
var command = {
name: commandNames.CHANGE_TEXT,
/**
* Change a text
* @param {Graphics} graphics - Graphics instance
* @param {number} id - object id
* @param {string} text - Changing text
* @returns {Promise}
*/
execute: function execute(graphics, id, text) {
var textComp = graphics.getComponent(TEXT);
var targetObj = graphics.getObject(id);
if (!targetObj) {
return _promise2.default.reject(rejectMessages.noObject);
}
this.undoData.object = targetObj;
this.undoData.text = textComp.getText(targetObj);
return textComp.change(targetObj, text);
},
/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
undo: function undo(graphics) {
var textComp = graphics.getComponent(TEXT);
var _undoData = this.undoData,
textObj = _undoData.object,
text = _undoData.text;
return textComp.change(textObj, text);
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 187 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _tuiCodeSnippet = __webpack_require__(3);
var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet);
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Change text styles
*/
var componentNames = _consts2.default.componentNames,
rejectMessages = _consts2.default.rejectMessages,
commandNames = _consts2.default.commandNames;
var TEXT = componentNames.TEXT;
var command = {
name: commandNames.CHANGE_TEXT_STYLE,
/**
* Change text styles
* @param {Graphics} graphics - Graphics instance
* @param {number} id - object id
* @param {Object} styles - text styles
* @param {string} [styles.fill] Color
* @param {string} [styles.fontFamily] Font type for text
* @param {number} [styles.fontSize] Size
* @param {string} [styles.fontStyle] Type of inclination (normal / italic)
* @param {string} [styles.fontWeight] Type of thicker or thinner looking (normal / bold)
* @param {string} [styles.textAlign] Type of text align (left / center / right)
* @param {string} [styles.textDecoraiton] Type of line (underline / line-throgh / overline)
* @param {Boolean} notReset - reset flag
* @returns {Promise}
*/
execute: function execute(graphics, id, styles, notReset) {
var _this = this;
var textComp = graphics.getComponent(TEXT);
var targetObj = graphics.getObject(id);
notReset = typeof notReset === 'undefined' ? false : notReset;
if (!targetObj) {
return _promise2.default.reject(rejectMessages.noObject);
}
this.undoData.object = targetObj;
this.undoData.styles = {};
this.undoData.notReset = notReset;
_tuiCodeSnippet2.default.forEachOwnProperties(styles, function (value, key) {
_this.undoData.styles[key] = targetObj[key];
});
return textComp.setStyle(targetObj, styles, notReset);
},
/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
undo: function undo(graphics) {
var textComp = graphics.getComponent(TEXT);
var _undoData = this.undoData,
textObj = _undoData.object,
styles = _undoData.styles,
notReset = _undoData.notReset;
return textComp.setStyle(textObj, styles, notReset);
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 188 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var commandNames = _consts2.default.commandNames; /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Clear all objects
*/
var command = {
name: commandNames.CLEAR_OBJECTS,
/**
* Clear all objects without background (main) image
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
execute: function execute(graphics) {
var _this = this;
return new _promise2.default(function (resolve) {
_this.undoData.objects = graphics.removeAll();
resolve();
});
},
/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
* @ignore
*/
undo: function undo(graphics) {
graphics.add(this.undoData.objects);
return _promise2.default.resolve();
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 189 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Flip an image
*/
var componentNames = _consts2.default.componentNames,
commandNames = _consts2.default.commandNames;
var FLIP = componentNames.FLIP;
var command = {
name: commandNames.FLIP_IMAGE,
/**
* flip an image
* @param {Graphics} graphics - Graphics instance
* @param {string} type - 'flipX' or 'flipY' or 'reset'
* @returns {Promise}
*/
execute: function execute(graphics, type) {
var flipComp = graphics.getComponent(FLIP);
this.undoData.setting = flipComp.getCurrentSetting();
return flipComp[type]();
},
/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
undo: function undo(graphics) {
var flipComp = graphics.getComponent(FLIP);
return flipComp.set(this.undoData.setting);
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 190 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Load a background (main) image
*/
var componentNames = _consts2.default.componentNames,
commandNames = _consts2.default.commandNames;
var IMAGE_LOADER = componentNames.IMAGE_LOADER;
var command = {
name: commandNames.LOAD_IMAGE,
/**
* Load a background (main) image
* @param {Graphics} graphics - Graphics instance
* @param {string} imageName - Image name
* @param {string} imgUrl - Image Url
* @returns {Promise}
*/
execute: function execute(graphics, imageName, imgUrl) {
var loader = graphics.getComponent(IMAGE_LOADER);
var prevImage = loader.getCanvasImage();
var prevImageWidth = prevImage ? prevImage.width : 0;
var prevImageHeight = prevImage ? prevImage.height : 0;
this.undoData = {
name: loader.getImageName(),
image: prevImage,
objects: graphics.removeAll(true)
};
return loader.load(imageName, imgUrl).then(function (newImage) {
return {
oldWidth: prevImageWidth,
oldHeight: prevImageHeight,
newWidth: newImage.width,
newHeight: newImage.height
};
});
},
/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
undo: function undo(graphics) {
var loader = graphics.getComponent(IMAGE_LOADER);
var _undoData = this.undoData,
objects = _undoData.objects,
name = _undoData.name,
image = _undoData.image;
graphics.removeAll(true);
graphics.add(objects);
return loader.load(name, image);
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 191 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Remove a filter from an image
*/
var componentNames = _consts2.default.componentNames,
commandNames = _consts2.default.commandNames;
var FILTER = componentNames.FILTER;
var command = {
name: commandNames.REMOVE_FILTER,
/**
* Remove a filter from an image
* @param {Graphics} graphics - Graphics instance
* @param {string} type - Filter type
* @returns {Promise}
*/
execute: function execute(graphics, type) {
var filterComp = graphics.getComponent(FILTER);
this.undoData.options = filterComp.getOptions(type);
return filterComp.remove(type);
},
/**
* @param {Graphics} graphics - Graphics instance
* @param {string} type - Filter type
* @returns {Promise}
*/
undo: function undo(graphics, type) {
var filterComp = graphics.getComponent(FILTER);
var options = this.undoData.options;
return filterComp.add(type, options);
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 192 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var commandNames = _consts2.default.commandNames,
rejectMessages = _consts2.default.rejectMessages; /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Remove an object
*/
var command = {
name: commandNames.REMOVE_OBJECT,
/**
* Remove an object
* @param {Graphics} graphics - Graphics instance
* @param {number} id - object id
* @returns {Promise}
*/
execute: function execute(graphics, id) {
var _this = this;
return new _promise2.default(function (resolve, reject) {
_this.undoData.objects = graphics.removeObjectById(id);
if (_this.undoData.objects.length) {
resolve();
} else {
reject(rejectMessages.noObject);
}
});
},
/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
undo: function undo(graphics) {
graphics.add(this.undoData.objects);
return _promise2.default.resolve();
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 193 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var commandNames = _consts2.default.commandNames; /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Resize a canvas
*/
var command = {
name: commandNames.RESIZE_CANVAS_DIMENSION,
/**
* resize the canvas with given dimension
* @param {Graphics} graphics - Graphics instance
* @param {{width: number, height: number}} dimension - Max width & height
* @returns {Promise}
*/
execute: function execute(graphics, dimension) {
var _this = this;
return new _promise2.default(function (resolve) {
_this.undoData.size = {
width: graphics.cssMaxWidth,
height: graphics.cssMaxHeight
};
graphics.setCssMaxDimension(dimension);
graphics.adjustCanvasDimension();
resolve();
});
},
/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
undo: function undo(graphics) {
graphics.setCssMaxDimension(this.undoData.size);
graphics.adjustCanvasDimension();
return _promise2.default.resolve();
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 194 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Rotate an image
*/
var componentNames = _consts2.default.componentNames,
commandNames = _consts2.default.commandNames;
var ROTATION = componentNames.ROTATION;
var command = {
name: commandNames.ROTATE_IMAGE,
/**
* Rotate an image
* @param {Graphics} graphics - Graphics instance
* @param {string} type - 'rotate' or 'setAngle'
* @param {number} angle - angle value (degree)
* @returns {Promise}
*/
execute: function execute(graphics, type, angle) {
var rotationComp = graphics.getComponent(ROTATION);
this.undoData.angle = rotationComp.getCurrentAngle();
return rotationComp[type](angle);
},
/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
undo: function undo(graphics) {
var rotationComp = graphics.getComponent(ROTATION);
var angle = this.undoData.angle;
return rotationComp.setAngle(angle);
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 195 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _tuiCodeSnippet = __webpack_require__(3);
var _tuiCodeSnippet2 = _interopRequireDefault(_tuiCodeSnippet);
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Set object properties
*/
var commandNames = _consts2.default.commandNames,
rejectMessages = _consts2.default.rejectMessages;
var command = {
name: commandNames.SET_OBJECT_PROPERTIES,
/**
* Set object properties
* @param {Graphics} graphics - Graphics instance
* @param {number} id - object id
* @param {Object} props - properties
* @param {string} [props.fill] Color
* @param {string} [props.fontFamily] Font type for text
* @param {number} [props.fontSize] Size
* @param {string} [props.fontStyle] Type of inclination (normal / italic)
* @param {string} [props.fontWeight] Type of thicker or thinner looking (normal / bold)
* @param {string} [props.textAlign] Type of text align (left / center / right)
* @param {string} [props.textDecoraiton] Type of line (underline / line-throgh / overline)
* @returns {Promise}
*/
execute: function execute(graphics, id, props) {
var _this = this;
var targetObj = graphics.getObject(id);
if (!targetObj) {
return _promise2.default.reject(rejectMessages.noObject);
}
this.undoData.props = {};
_tuiCodeSnippet2.default.forEachOwnProperties(props, function (value, key) {
_this.undoData.props[key] = targetObj[key];
});
graphics.setObjectProperties(id, props);
return _promise2.default.resolve();
},
/**
* @param {Graphics} graphics - Graphics instance
* @param {number} id - object id
* @returns {Promise}
*/
undo: function undo(graphics, id) {
var props = this.undoData.props;
graphics.setObjectProperties(id, props);
return _promise2.default.resolve();
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 196 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var commandNames = _consts2.default.commandNames,
rejectMessages = _consts2.default.rejectMessages; /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Set object properties
*/
var command = {
name: commandNames.SET_OBJECT_POSITION,
/**
* Set object properties
* @param {Graphics} graphics - Graphics instance
* @param {number} id - object id
* @param {Object} posInfo - position object
* @param {number} posInfo.x - x position
* @param {number} posInfo.y - y position
* @param {string} posInfo.originX - can be 'left', 'center', 'right'
* @param {string} posInfo.originY - can be 'top', 'center', 'bottom'
* @returns {Promise}
*/
execute: function execute(graphics, id, posInfo) {
var targetObj = graphics.getObject(id);
if (!targetObj) {
return _promise2.default.reject(rejectMessages.noObject);
}
this.undoData.objectId = id;
this.undoData.props = graphics.getObjectProperties(id, ['left', 'top']);
graphics.setObjectPosition(id, posInfo);
graphics.renderAll();
return _promise2.default.resolve();
},
/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
undo: function undo(graphics) {
var _undoData = this.undoData,
objectId = _undoData.objectId,
props = _undoData.props;
graphics.setObjectProperties(objectId, props);
graphics.renderAll();
return _promise2.default.resolve();
}
};
_command2.default.register(command);
module.exports = command;
/***/ }),
/* 197 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
var _command = __webpack_require__(69);
var _command2 = _interopRequireDefault(_command);
var _promise = __webpack_require__(4);
var _promise2 = _interopRequireDefault(_promise);
var _consts = __webpack_require__(73);
var _consts2 = _interopRequireDefault(_consts);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var commandNames = _consts2.default.commandNames; /**
* @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
* @fileoverview Set object properties
*/
var command = {
name: commandNames.SET_OBJECT_POSITIONS,
/**
* Set object properties
* @param {Graphics} graphics - Graphics instance
* @param {array} settings - object id
* @param {Object} posInfo - position object
* @param {number} posInfo.x - x position
* @param {number} posInfo.y - y position
* @param {string} posInfo.originX - can be 'left', 'center', 'right'
* @param {string} posInfo.originY - can be 'top', 'center', 'bottom'
* @returns {Promise}
*/
execute: function execute(graphics, settings) {
this.undoData.propsList = [];
var set = null;
var targetObj = null;
for (var i = 0; i < settings.length; i += 1) {
set = settings[i];
targetObj = graphics.getObject(set.id);
if (targetObj) {
this.undoData.propsList.push({
id: set.id,
props: graphics.getObjectProperties(set.id, ['left', 'top'])
});
graphics.setObjectPosition(set.id, set.posInfo);
}
}
graphics.renderAll();
return _promise2.default.resolve();
},
/**
* @param {Graphics} graphics - Graphics instance
* @returns {Promise}
*/
undo: function undo(graphics) {
for (var index = 0; index < this.undoData.propsList.length; index += 1) {
var _undoData$propsList$i = this.undoData.propsList[index],
id = _undoData$propsList$i.id,
props = _undoData$propsList$i.props;
graphics.setObjectProperties(id, props);
}
graphics.renderAll();
return _promise2.default.resolve();
}
};
_command2.default.register(command);
module.exports = command;
/***/ })
/******/ ])
});
;