(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i 10.'); } else { registerFileDrop(container, openDiagram); } // bootstrap diagram functions (0, _jquery2.default)(function () { (0, _jquery2.default)('#js-create-diagram').click(function (e) { e.stopPropagation(); e.preventDefault(); createNewDiagram(); }); var downloadLink = (0, _jquery2.default)('#js-download-diagram'); var downloadSvgLink = (0, _jquery2.default)('#js-download-svg'); (0, _jquery2.default)('.buttons a').click(function (e) { if (!(0, _jquery2.default)(this).is('.active')) { e.preventDefault(); e.stopPropagation(); } }); function setEncoded(link, name, data) { var encodedData = encodeURIComponent(data); if (data) { link.addClass('active').attr({ 'href': 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData, 'download': name }); } else { link.removeClass('active'); } } var exportArtifacts = (0, _minDash.debounce)(function () { saveSVG(function (err, svg) { setEncoded(downloadSvgLink, 'diagram.svg', err ? null : svg); }); saveDiagram(function (err, xml) { setEncoded(downloadLink, 'diagram.bpmn', err ? null : xml); }); }, 500); bpmnModeler.on('commandStack.changed', exportArtifacts); }); },{"../resources/newDiagram.bpmn":536,"bpmn-js-properties-panel":2,"bpmn-js-properties-panel/lib/provider/camunda":62,"bpmn-js/lib/Modeler":114,"camunda-bpmn-moddle/resources/camunda":229,"jquery":416,"min-dash":505}],2:[function(require,module,exports){ 'use strict'; module.exports = require('./lib'); },{"./lib":32}],3:[function(require,module,exports){ 'use strict'; var DEFAULT_PRIORITY = 1000; /** * A component that decides upon the visibility / editable * state of properties in the properties panel. * * Implementors must subclass this component and override * {@link PropertiesActivator#isEntryVisible} and * {@link PropertiesActivator#isPropertyEditable} to provide * custom behavior. * * @class * @constructor * * @param {EventBus} eventBus * @param {Number} [priority] at which priority to hook into the activation */ function PropertiesActivator(eventBus, priority) { var self = this; priority = priority || DEFAULT_PRIORITY; eventBus.on('propertiesPanel.isEntryVisible', priority, function (e) { return self.isEntryVisible(e.entry, e.element); }); eventBus.on('propertiesPanel.isPropertyEditable', priority, function (e) { return self.isPropertyEditable(e.entry, e.propertyName, e.element); }); } PropertiesActivator.$inject = ['eventBus']; module.exports = PropertiesActivator; /** * Should the given entry be visible for the specified element. * * @method PropertiesActivator#isEntryVisible * * @param {EntryDescriptor} entry * @param {ModdleElement} element * * @returns {Boolean} */ PropertiesActivator.prototype.isEntryVisible = function (entry, element) { return true; }; /** * Should the given property be editable for the specified element * * @method PropertiesActivator#isPropertyEditable * * @param {EntryDescriptor} entry * @param {String} propertyName * @param {ModdleElement} element * * @returns {Boolean} */ PropertiesActivator.prototype.isPropertyEditable = function (entry, propertyName, element) { return true; }; },{}],4:[function(require,module,exports){ 'use strict'; var domify = require('min-dom/lib/domify'), domQuery = require('min-dom/lib/query'), domRemove = require('min-dom/lib/remove'), domClasses = require('min-dom/lib/classes'), domClosest = require('min-dom/lib/closest'), domAttr = require('min-dom/lib/attr'), domDelegate = require('min-dom/lib/delegate'), domMatches = require('min-dom/lib/matches'); var forEach = require('lodash/collection/forEach'), filter = require('lodash/collection/filter'), get = require('lodash/object/get'), keys = require('lodash/object/keys'), isEmpty = require('lodash/lang/isEmpty'), isArray = require('lodash/lang/isArray'), xor = require('lodash/array/xor'), debounce = require('lodash/function/debounce'); var updateSelection = require('selection-update'); var scrollTabs = require('scroll-tabs'); var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var HIDE_CLASS = 'bpp-hidden'; var DEBOUNCE_DELAY = 300; function isToggle(node) { return node.type === 'checkbox' || node.type === 'radio'; } function isSelect(node) { return node.type === 'select-one'; } function isContentEditable(node) { return domAttr(node, 'contenteditable'); } function getPropertyPlaceholders(node) { var selector = 'input[name], textarea[name], [data-value], [contenteditable]'; var placeholders = domQuery.all(selector, node); if ((!placeholders || !placeholders.length) && domMatches(node, selector)) { placeholders = [node]; } return placeholders; } /** * Return all active form controls. * This excludes the invisible controls unless all is true * * @param {Element} node * @param {Boolean} [all=false] */ function getFormControls(node, all) { var controls = domQuery.all('input[name], textarea[name], select[name], [contenteditable]', node); if (!controls || !controls.length) { controls = domMatches(node, 'option') ? [node] : controls; } if (!all) { controls = filter(controls, function (node) { return !domClosest(node, '.' + HIDE_CLASS); }); } return controls; } function getFormControlValuesInScope(entryNode) { var values = {}; var controlNodes = getFormControls(entryNode); forEach(controlNodes, function (controlNode) { var value = controlNode.value; var name = domAttr(controlNode, 'name') || domAttr(controlNode, 'data-name'); // take toggle state into account for radio / checkboxes if (isToggle(controlNode)) { if (controlNode.checked) { if (!domAttr(controlNode, 'value')) { value = true; } else { value = controlNode.value; } } else { value = null; } } else if (isContentEditable(controlNode)) { value = controlNode.innerText; } if (value !== null) { // return the actual value // handle serialization in entry provider // (ie. if empty string should be serialized or not) values[name] = value; } }); return values; } /** * Extract input values from entry node * * @param {DOMElement} entryNode * @returns {Object} */ function getFormControlValues(entryNode) { var values; var listContainer = domQuery('[data-list-entry-container]', entryNode); if (listContainer) { values = []; var listNodes = listContainer.children || []; forEach(listNodes, function (listNode) { values.push(getFormControlValuesInScope(listNode)); }); } else { values = getFormControlValuesInScope(entryNode); } return values; } /** * Return true if the given form extracted value equals * to an old cached version. * * @param {Object} value * @param {Object} oldValue * @return {Boolean} */ function valueEqual(value, oldValue) { if (value && !oldValue) { return false; } var allKeys = keys(value).concat(keys(oldValue)); return allKeys.every(function (key) { return value[key] === oldValue[key]; }); } /** * Return true if the given form extracted value(s) * equal an old cached version. * * @param {Array|Object} values * @param {Array|Object} oldValues * @return {Boolean} */ function valuesEqual(values, oldValues) { if (isArray(values)) { if (values.length !== oldValues.length) { return false; } return values.every(function (v, idx) { return valueEqual(v, oldValues[idx]); }); } return valueEqual(values, oldValues); } /** * Return a mapping of { id: entry } for all entries in the given groups in the given tabs. * * @param {Object} tabs * @return {Object} */ function extractEntries(tabs) { return indexBy(flattenDeep(map(flattenDeep(map(tabs, 'groups')), 'entries')), 'id'); } /** * Return a mapping of { id: group } for all groups in the given tabs. * * @param {Object} tabs * @return {Object} */ function extractGroups(tabs) { return indexBy(flattenDeep(map(tabs, 'groups')), 'id'); } /** * A properties panel implementation. * * To use it provide a `propertiesProvider` component that knows * about which properties to display. * * Properties edit state / visibility can be intercepted * via a custom {@link PropertiesActivator}. * * @class * @constructor * * @param {Object} config * @param {EventBus} eventBus * @param {Modeling} modeling * @param {PropertiesProvider} propertiesProvider * @param {Canvas} canvas * @param {CommandStack} commandStack */ function PropertiesPanel(config, eventBus, modeling, propertiesProvider, commandStack, canvas) { this._eventBus = eventBus; this._modeling = modeling; this._commandStack = commandStack; this._canvas = canvas; this._propertiesProvider = propertiesProvider; this._init(config); } PropertiesPanel.$inject = ['config.propertiesPanel', 'eventBus', 'modeling', 'propertiesProvider', 'commandStack', 'canvas']; module.exports = PropertiesPanel; PropertiesPanel.prototype._init = function (config) { var eventBus = this._eventBus; var self = this; /** * Select the root element once it is added to the canvas */ eventBus.on('root.added', function (e) { self.update(e.element); }); eventBus.on('selection.changed', function (e) { var newElement = e.newSelection[0]; self.update(newElement); }); // add / update tab-bar scrolling eventBus.on(['propertiesPanel.changed', 'propertiesPanel.resized'], function (event) { var tabBarNode = domQuery('.bpp-properties-tab-bar', self._container); if (!tabBarNode) { return; } var scroller = scrollTabs.get(tabBarNode); if (!scroller) { // we did not initialize yet, do that // now and make sure we select the active // tab on scroll update scroller = scrollTabs(tabBarNode, { selectors: { tabsContainer: '.bpp-properties-tabs-links', tab: '.bpp-properties-tabs-links li', ignore: '.bpp-hidden', active: '.bpp-active' } }); scroller.on('scroll', function (newActiveNode, oldActiveNode, direction) { var linkNode = domQuery('[data-tab-target]', newActiveNode); var tabId = domAttr(linkNode, 'data-tab-target'); self.activateTab(tabId); }); } // react on tab changes and or tabContainer resize // and make sure the active tab is shown completely scroller.update(); }); eventBus.on('elements.changed', function (e) { var current = self._current; var element = current && current.element; if (element) { if (e.elements.indexOf(element) !== -1) { self.update(element); } } }); eventBus.on('elementTemplates.changed', function () { var current = self._current; var element = current && current.element; if (element) { self.update(element); } }); eventBus.on('diagram.destroy', function () { self.detach(); }); this._container = domify('
'); this._bindListeners(this._container); if (config && config.parent) { this.attachTo(config.parent); } }; PropertiesPanel.prototype.attachTo = function (parentNode) { if (!parentNode) { throw new Error('parentNode required'); } // ensure we detach from the // previous, old parent this.detach(); // unwrap jQuery if provided if (parentNode.get && parentNode.constructor.prototype.jquery) { parentNode = parentNode.get(0); } if (typeof parentNode === 'string') { parentNode = domQuery(parentNode); } var container = this._container; parentNode.appendChild(container); this._emit('attach'); }; PropertiesPanel.prototype.detach = function () { var container = this._container, parentNode = container.parentNode; if (!parentNode) { return; } this._emit('detach'); parentNode.removeChild(container); }; /** * Select the given tab within the properties panel. * * @param {Object|String} tab */ PropertiesPanel.prototype.activateTab = function (tab) { var tabId = typeof tab === 'string' ? tab : tab.id; var current = this._current; var panelNode = current.panel; var allTabNodes = domQuery.all('.bpp-properties-tab', panelNode), allTabLinkNodes = domQuery.all('.bpp-properties-tab-link', panelNode); forEach(allTabNodes, function (tabNode) { var currentTabId = domAttr(tabNode, 'data-tab'); domClasses(tabNode).toggle('bpp-active', tabId === currentTabId); }); forEach(allTabLinkNodes, function (tabLinkNode) { var tabLink = domQuery('[data-tab-target]', tabLinkNode), currentTabId = domAttr(tabLink, 'data-tab-target'); domClasses(tabLinkNode).toggle('bpp-active', tabId === currentTabId); }); }; /** * Update the DOM representation of the properties panel */ PropertiesPanel.prototype.update = function (element) { var current = this._current; // no actual selection change var needsCreate = true; if (typeof element === 'undefined') { // use RootElement of BPMN diagram to generate properties panel if no element is selected element = this._canvas.getRootElement(); } var newTabs = this._propertiesProvider.getTabs(element); if (current && current.element === element) { // see if we can reuse the existing panel needsCreate = this._entriesChanged(current, newTabs); } if (needsCreate) { if (current) { // get active tab from the existing panel before remove it var activeTabNode = domQuery('.bpp-properties-tab.bpp-active', current.panel); var activeTabId; if (activeTabNode) { activeTabId = domAttr(activeTabNode, 'data-tab'); } // remove old panel domRemove(current.panel); } this._current = this._create(element, newTabs); // activate the saved active tab from the remove panel or the first tab activeTabId ? this.activateTab(activeTabId) : this.activateTab(this._current.tabs[0]); } if (this._current) { // make sure correct tab contents are visible this._updateActivation(this._current); } this._emit('changed'); }; /** * Returns true if one of two groups has different entries than the other. * * @param {Object} current * @param {Object} newTabs * @return {Booelan} */ PropertiesPanel.prototype._entriesChanged = function (current, newTabs) { var oldEntryIds = keys(current.entries), newEntryIds = keys(extractEntries(newTabs)); return !isEmpty(xor(oldEntryIds, newEntryIds)); }; PropertiesPanel.prototype._emit = function (event) { this._eventBus.fire('propertiesPanel.' + event, { panel: this, current: this._current }); }; PropertiesPanel.prototype._bindListeners = function (container) { var self = this; // handles a change for a given event var handleChange = function handleChange(event) { // see if we handle a change inside a [data-entry] element. // if not, drop out var node = domClosest(event.delegateTarget, '[data-entry]'), entryId, entry; // change from outside a [data-entry] element, simply ignore if (!node) { return; } entryId = domAttr(node, 'data-entry'); entry = self.getEntry(entryId); var values = getFormControlValues(node); if (event.type === 'change') { // - if the "data-on-change" attribute is present and a value is changed, // then the associated action is performed. // - if the associated action returns "true" then an update to the business // object is done // - if it does not return "true", then only the DOM content is updated var onChangeAction = event.delegateTarget.getAttribute('data-on-change'); if (onChangeAction) { var isEntryDirty = self.executeAction(entry, node, onChangeAction, event); if (!isEntryDirty) { return self.update(self._current.element); } } } self.applyChanges(entry, values, node); self.updateState(entry, node); }; // debounce update only elements that are target of key events, // i.e. INPUT and TEXTAREA. SELECTs will trigger an immediate update anyway. domDelegate.bind(container, 'input, textarea, [contenteditable]', 'input', debounce(handleChange, DEBOUNCE_DELAY)); domDelegate.bind(container, 'input, textarea, select, [contenteditable]', 'change', handleChange); domDelegate.bind(container, '[data-action]', 'click', function onClick(event) { // triggers on all inputs var inputNode = event.delegateTarget; var entryNode = domClosest(inputNode, '[data-entry]'); var actionId = domAttr(inputNode, 'data-action'), entryId = domAttr(entryNode, 'data-entry'); var entry = self.getEntry(entryId); var isEntryDirty = self.executeAction(entry, entryNode, actionId, event); if (isEntryDirty) { var values = getFormControlValues(entryNode); self.applyChanges(entry, values, entryNode); } self.updateState(entry, entryNode); }); function handleInput(event, element) { // triggers on all inputs var inputNode = event.delegateTarget; var entryNode = domClosest(inputNode, '[data-entry]'); // only work on data entries if (!entryNode) { return; } var eventHandlerId = domAttr(inputNode, 'data-blur'), entryId = domAttr(entryNode, 'data-entry'); var entry = self.getEntry(entryId); var isEntryDirty = self.executeAction(entry, entryNode, eventHandlerId, event); if (isEntryDirty) { var values = getFormControlValues(entryNode); self.applyChanges(entry, values, entryNode); } self.updateState(entry, entryNode); } domDelegate.bind(container, '[data-blur]', 'blur', handleInput, true); // make tab links interactive domDelegate.bind(container, '.bpp-properties-tabs-links [data-tab-target]', 'click', function (event) { event.preventDefault(); var delegateTarget = event.delegateTarget; var tabId = domAttr(delegateTarget, 'data-tab-target'); // activate tab on link click self.activateTab(tabId); }); }; PropertiesPanel.prototype.updateState = function (entry, entryNode) { this.updateShow(entry, entryNode); this.updateDisable(entry, entryNode); }; /** * Update the visibility of the entry node in the DOM */ PropertiesPanel.prototype.updateShow = function (entry, node) { var current = this._current; if (!current) { return; } var showNodes = domQuery.all('[data-show]', node) || []; forEach(showNodes, function (showNode) { var expr = domAttr(showNode, 'data-show'); var fn = get(entry, expr); if (fn) { var scope = domClosest(showNode, '[data-scope]') || node; var shouldShow = fn(current.element, node, showNode, scope) || false; if (shouldShow) { domClasses(showNode).remove(HIDE_CLASS); } else { domClasses(showNode).add(HIDE_CLASS); } } }); }; /** * Evaluates a given function. If it returns true, then the * node is marked as "disabled". */ PropertiesPanel.prototype.updateDisable = function (entry, node) { var current = this._current; if (!current) { return; } var nodes = domQuery.all('[data-disable]', node) || []; forEach(nodes, function (currentNode) { var expr = domAttr(currentNode, 'data-disable'); var fn = get(entry, expr); if (fn) { var scope = domClosest(currentNode, '[data-scope]') || node; var shouldDisable = fn(current.element, node, currentNode, scope) || false; domAttr(currentNode, 'disabled', shouldDisable ? '' : null); } }); }; PropertiesPanel.prototype.executeAction = function (entry, entryNode, actionId, event) { var current = this._current; if (!current) { return; } var fn = get(entry, actionId); if (fn) { var scopeNode = domClosest(event.target, '[data-scope]') || entryNode; return fn.apply(entry, [current.element, entryNode, event, scopeNode]); } }; /** * Apply changes to the business object by executing a command */ PropertiesPanel.prototype.applyChanges = function (entry, values, containerElement) { var element = this._current.element; // ensure we only update the model if we got dirty changes if (valuesEqual(values, entry.oldValues)) { return; } var command = entry.set(element, values, containerElement); var commandToExecute; if (isArray(command)) { if (command.length) { commandToExecute = { cmd: 'properties-panel.multi-command-executor', context: flattenDeep(command) }; } } else { commandToExecute = command; } if (commandToExecute) { this._commandStack.execute(commandToExecute.cmd, commandToExecute.context || { element: element }); } else { this.update(element); } }; /** * apply validation errors in the DOM and show or remove an error message near the entry node. */ PropertiesPanel.prototype.applyValidationErrors = function (validationErrors, entryNode) { var valid = true; var controlNodes = getFormControls(entryNode, true); forEach(controlNodes, function (controlNode) { var name = domAttr(controlNode, 'name') || domAttr(controlNode, 'data-name'); var error = validationErrors && validationErrors[name]; var errorMessageNode = domQuery('.bpp-error-message', controlNode.parentNode); if (error) { valid = false; if (!errorMessageNode) { errorMessageNode = domify('
'); domClasses(errorMessageNode).add('bpp-error-message'); // insert errorMessageNode after controlNode controlNode.parentNode.insertBefore(errorMessageNode, controlNode.nextSibling); } errorMessageNode.innerHTML = error; domClasses(controlNode).add('invalid'); } else { domClasses(controlNode).remove('invalid'); if (errorMessageNode) { controlNode.parentNode.removeChild(errorMessageNode); } } }); return valid; }; /** * Check if the entry contains valid input */ PropertiesPanel.prototype.validate = function (entry, values, entryNode) { var self = this; var current = this._current; var valid = true; entryNode = entryNode || domQuery('[data-entry="' + entry.id + '"]', current.panel); if (values instanceof Array) { var listContainer = domQuery('[data-list-entry-container]', entryNode), listEntryNodes = listContainer.children || []; // create new elements for (var i = 0; i < values.length; i++) { var listValue = values[i]; if (entry.validateListItem) { var validationErrors = entry.validateListItem(current.element, listValue, entryNode, i), listEntryNode = listEntryNodes[i]; valid = self.applyValidationErrors(validationErrors, listEntryNode) && valid; } } } else { if (entry.validate) { this.validationErrors = entry.validate(current.element, values, entryNode); valid = self.applyValidationErrors(this.validationErrors, entryNode) && valid; } } return valid; }; PropertiesPanel.prototype.getEntry = function (id) { return this._current && this._current.entries[id]; }; var flattenDeep = require('lodash/array/flattenDeep'), indexBy = require('lodash/collection/indexBy'), map = require('lodash/collection/map'); PropertiesPanel.prototype._create = function (element, tabs) { if (!element) { return null; } var containerNode = this._container; var panelNode = this._createPanel(element, tabs); containerNode.appendChild(panelNode); var entries = extractEntries(tabs); var groups = extractGroups(tabs); return { tabs: tabs, groups: groups, entries: entries, element: element, panel: panelNode }; }; /** * Update variable parts of the entry node on element changes. * * @param {djs.model.Base} element * @param {EntryDescriptor} entry * @param {Object} values * @param {HTMLElement} entryNode * @param {Number} idx */ PropertiesPanel.prototype._bindTemplate = function (element, entry, values, entryNode, idx) { var eventBus = this._eventBus; function isPropertyEditable(entry, propertyName) { return eventBus.fire('propertiesPanel.isPropertyEditable', { entry: entry, propertyName: propertyName, element: element }); } var inputNodes = getPropertyPlaceholders(entryNode); forEach(inputNodes, function (node) { var name, newValue, editable; // we deal with an input element if ('value' in node || isContentEditable(node) === 'true') { name = domAttr(node, 'name') || domAttr(node, 'data-name'); newValue = values[name]; editable = isPropertyEditable(entry, name); if (editable && entry.editable) { editable = entry.editable(element, entryNode, node, name, newValue, idx); } domAttr(node, 'readonly', editable ? null : ''); domAttr(node, 'disabled', editable ? null : ''); // take full control over setting the value // and possibly updating the input in entry#setControlValue if (entry.setControlValue) { entry.setControlValue(element, entryNode, node, name, newValue, idx); } else if (isToggle(node)) { setToggleValue(node, newValue); } else if (isSelect(node)) { setSelectValue(node, newValue); } else { setInputValue(node, newValue); } } // we deal with some non-editable html element else { name = domAttr(node, 'data-value'); newValue = values[name]; if (entry.setControlValue) { entry.setControlValue(element, entryNode, node, name, newValue, idx); } else { setTextValue(node, newValue); } } }); }; // TODO(nikku): WTF freaking name? Change / clarify. PropertiesPanel.prototype._updateActivation = function (current) { var self = this; var eventBus = this._eventBus; var element = current.element; function isEntryVisible(entry) { return eventBus.fire('propertiesPanel.isEntryVisible', { entry: entry, element: element }); } function isGroupVisible(group, element, groupNode) { if (typeof group.enabled === 'function') { return group.enabled(element, groupNode); } else { return true; } } function isTabVisible(tab, element) { if (typeof tab.enabled === 'function') { return tab.enabled(element); } else { return true; } } function toggleVisible(node, visible) { domClasses(node).toggle(HIDE_CLASS, !visible); } // check whether the active tab is visible // if not: set the first tab as active tab function checkActiveTabVisibility(node, visible) { var isActive = domClasses(node).has('bpp-active'); if (!visible && isActive) { self.activateTab(current.tabs[0]); } } function updateLabel(element, selector, text) { var labelNode = domQuery(selector, element); if (!labelNode) { return; } labelNode.textContent = text; } var panelNode = current.panel; forEach(current.tabs, function (tab) { var tabNode = domQuery('[data-tab=' + tab.id + ']', panelNode); var tabLinkNode = domQuery('[data-tab-target=' + tab.id + ']', panelNode).parentNode; var tabVisible = false; forEach(tab.groups, function (group) { var groupVisible = false; var groupNode = domQuery('[data-group=' + group.id + ']', tabNode); forEach(group.entries, function (entry) { var entryNode = domQuery('[data-entry="' + entry.id + '"]', groupNode); var entryVisible = isEntryVisible(entry); groupVisible = groupVisible || entryVisible; toggleVisible(entryNode, entryVisible); var values = 'get' in entry ? entry.get(element, entryNode) : {}; if (values instanceof Array) { var listEntryContainer = domQuery('[data-list-entry-container]', entryNode); var existingElements = listEntryContainer.children || []; for (var i = 0; i < values.length; i++) { var listValue = values[i]; var listItemNode = existingElements[i]; if (!listItemNode) { listItemNode = domify(entry.createListEntryTemplate(listValue, i, listEntryContainer)); listEntryContainer.appendChild(listItemNode); } domAttr(listItemNode, 'data-index', i); self._bindTemplate(element, entry, listValue, listItemNode, i); } var entriesToRemove = existingElements.length - values.length; for (var j = 0; j < entriesToRemove; j++) { // remove orphaned element listEntryContainer.removeChild(listEntryContainer.lastChild); } } else { self._bindTemplate(element, entry, values, entryNode); } // update conditionally visible elements self.updateState(entry, entryNode); self.validate(entry, values, entryNode); // remember initial state for later dirty checking entry.oldValues = getFormControlValues(entryNode); }); if (typeof group.label === 'function') { updateLabel(groupNode, '.group-label', group.label(element, groupNode)); } groupVisible = groupVisible && isGroupVisible(group, element, groupNode); tabVisible = tabVisible || groupVisible; toggleVisible(groupNode, groupVisible); }); tabVisible = tabVisible && isTabVisible(tab, element); toggleVisible(tabNode, tabVisible); toggleVisible(tabLinkNode, tabVisible); checkActiveTabVisibility(tabNode, tabVisible); }); // inject elements id into header updateLabel(panelNode, '[data-label-id]', getBusinessObject(element).id || ''); }; PropertiesPanel.prototype._createPanel = function (element, tabs) { var self = this; var panelNode = domify('
'), headerNode = domify('
' + '
' + '' + '
'), tabBarNode = domify('
'), tabLinksNode = domify(''), tabContainerNode = domify('
'); panelNode.appendChild(headerNode); forEach(tabs, function (tab, tabIndex) { if (!tab.id) { throw new Error('tab must have an id'); } var tabNode = domify('
'), tabLinkNode = domify(''); var groups = tab.groups; forEach(groups, function (group) { if (!group.id) { throw new Error('group must have an id'); } var groupNode = domify('
' + '' + '' + group.label + '' + '
'); // TODO(nre): use event delegation to handle that... groupNode.querySelector('.group-toggle').addEventListener('click', function (evt) { domClasses(groupNode).toggle('group-closed'); evt.preventDefault(); evt.stopPropagation(); }); groupNode.addEventListener('click', function (evt) { if (!evt.defaultPrevented && domClasses(groupNode).has('group-closed')) { domClasses(groupNode).remove('group-closed'); } }); forEach(group.entries, function (entry) { if (!entry.id) { throw new Error('entry must have an id'); } var html = entry.html; if (typeof html === 'string') { html = domify(html); } // unwrap jquery if (html.get && html.constructor.prototype.jquery) { html = html.get(0); } var entryNode = domify('
'); forEach(entry.cssClasses || [], function (cssClass) { domClasses(entryNode).add(cssClass); }); entryNode.appendChild(html); groupNode.appendChild(entryNode); // update conditionally visible elements self.updateState(entry, entryNode); }); tabNode.appendChild(groupNode); }); tabLinksNode.appendChild(tabLinkNode); tabContainerNode.appendChild(tabNode); }); tabBarNode.appendChild(tabLinksNode); panelNode.appendChild(tabBarNode); panelNode.appendChild(tabContainerNode); return panelNode; }; function setInputValue(node, value) { var contentEditable = isContentEditable(node); var oldValue = contentEditable ? node.innerText : node.value; var selection; // prevents input fields from having the value 'undefined' if (value === undefined) { value = ''; } if (oldValue === value) { return; } // update selection on undo/redo if (document.activeElement === node) { selection = updateSelection(getSelection(node), oldValue, value); } if (contentEditable) { node.innerText = value; } else { node.value = value; } if (selection) { setSelection(node, selection); } } function setSelectValue(node, value) { if (value !== undefined) { node.value = value; } } function setToggleValue(node, value) { var nodeValue = node.value; node.checked = value === nodeValue || !domAttr(node, 'value') && value; } function setTextValue(node, value) { node.textContent = value; } function getSelection(node) { return isContentEditable(node) ? getContentEditableSelection(node) : { start: node.selectionStart, end: node.selectionEnd }; } function getContentEditableSelection(node) { var selection = window.getSelection(); var focusNode = selection.focusNode, focusOffset = selection.focusOffset, anchorOffset = selection.anchorOffset; if (!focusNode) { throw new Error('not selected'); } // verify we have selection on the current element if (!node.contains(focusNode)) { throw new Error('not selected'); } return { start: Math.min(focusOffset, anchorOffset), end: Math.max(focusOffset, anchorOffset) }; } function setSelection(node, selection) { if (isContentEditable(node)) { setContentEditableSelection(node, selection); } else { node.selectionStart = selection.start; node.selectionEnd = selection.end; } } function setContentEditableSelection(node, selection) { var focusNode, domRange, domSelection; focusNode = node.firstChild || node, domRange = document.createRange(); domRange.setStart(focusNode, selection.start); domRange.setEnd(focusNode, selection.end); domSelection = window.getSelection(); domSelection.removeAllRanges(); domSelection.addRange(domRange); } },{"bpmn-js/lib/util/ModelUtil":216,"lodash/array/flattenDeep":417,"lodash/array/xor":419,"lodash/collection/filter":420,"lodash/collection/forEach":422,"lodash/collection/indexBy":423,"lodash/collection/map":424,"lodash/function/debounce":426,"lodash/lang/isArray":489,"lodash/lang/isEmpty":490,"lodash/object/get":497,"lodash/object/keys":498,"min-dom/lib/attr":105,"min-dom/lib/classes":106,"min-dom/lib/closest":108,"min-dom/lib/delegate":109,"min-dom/lib/domify":110,"min-dom/lib/matches":111,"min-dom/lib/query":112,"min-dom/lib/remove":113,"scroll-tabs":525,"selection-update":533}],5:[function(require,module,exports){ 'use strict'; var domQuery = require('min-dom/lib/query'), domClear = require('min-dom/lib/clear'), is = require('bpmn-js/lib/util/ModelUtil').is, forEach = require('lodash/collection/forEach'), domify = require('min-dom/lib/domify'), Ids = require('ids'); var SPACE_REGEX = /\s/; // for QName validation as per http://www.w3.org/TR/REC-xml/#NT-NameChar var QNAME_REGEX = /^([a-z][\w-.]*:)?[a-z_][\w-.]*$/i; // for ID validation as per BPMN Schema (QName - Namespace) var ID_REGEX = /^[a-z_][\w-.]*$/i; var PLACEHOLDER_REGEX = /\$\{([^\}]*)\}/g; function selectedOption(selectBox) { if (selectBox.selectedIndex >= 0) { return selectBox.options[selectBox.selectedIndex].value; } } module.exports.selectedOption = selectedOption; function selectedType(elementSyntax, inputNode) { var typeSelect = domQuery(elementSyntax, inputNode); return selectedOption(typeSelect); } module.exports.selectedType = selectedType; /** * Retrieve the root element the document this * business object is contained in. * * @return {ModdleElement} */ function getRoot(businessObject) { var parent = businessObject; while (parent.$parent) { parent = parent.$parent; } return parent; } module.exports.getRoot = getRoot; /** * filters all elements in the list which have a given type. * removes a new list */ function filterElementsByType(objectList, type) { var list = objectList || []; var result = []; forEach(list, function (obj) { if (is(obj, type)) { result.push(obj); } }); return result; } module.exports.filterElementsByType = filterElementsByType; function findRootElementsByType(businessObject, referencedType) { var root = getRoot(businessObject); return filterElementsByType(root.rootElements, referencedType); } module.exports.findRootElementsByType = findRootElementsByType; function removeAllChildren(domElement) { while (domElement.firstChild) { domElement.removeChild(domElement.firstChild); } } module.exports.removeAllChildren = removeAllChildren; /** * adds an empty option to the list */ function addEmptyParameter(list) { return list.push({ 'label': '', 'value': '', 'name': '' }); } module.exports.addEmptyParameter = addEmptyParameter; /** * returns a list with all root elements for the given parameter 'referencedType' */ function refreshOptionsModel(businessObject, referencedType) { var model = []; var referableObjects = findRootElementsByType(businessObject, referencedType); forEach(referableObjects, function (obj) { model.push({ label: (obj.name || '') + ' (id=' + obj.id + ')', value: obj.id, name: obj.name }); }); return model; } module.exports.refreshOptionsModel = refreshOptionsModel; /** * fills the drop down with options */ function updateOptionsDropDown(domSelector, businessObject, referencedType, entryNode) { var options = refreshOptionsModel(businessObject, referencedType); addEmptyParameter(options); var selectBox = domQuery(domSelector, entryNode); domClear(selectBox); forEach(options, function (option) { var optionEntry = domify(''); selectBox.appendChild(optionEntry); }); return options; } module.exports.updateOptionsDropDown = updateOptionsDropDown; /** * checks whether the id value is valid * * @param {ModdleElement} bo * @param {String} idValue * * @return {String} error message */ function isIdValid(bo, idValue) { var assigned = bo.$model.ids.assigned(idValue); var idExists = assigned && assigned !== bo; if (!idValue || idExists) { return 'Element must have an unique id.'; } return validateId(idValue); } module.exports.isIdValid = isIdValid; function validateId(idValue) { idValue = stripPlaceholders(idValue); if (containsSpace(idValue)) { return 'Id must not contain spaces.'; } if (!ID_REGEX.test(idValue)) { if (QNAME_REGEX.test(idValue)) { return 'Id must not contain prefix.'; } return 'Id must be a valid QName.'; } } module.exports.validateId = validateId; function containsSpace(value) { return SPACE_REGEX.test(value); } module.exports.containsSpace = containsSpace; function stripPlaceholders(idValue) { // replace expression e.g. ${VERSION_TAG} // use only the content between ${} // for the REGEX check return idValue.replace(PLACEHOLDER_REGEX, '$1'); } /** * generate a semantic id with given prefix */ function nextId(prefix) { var ids = new Ids([32, 32, 1]); return ids.nextPrefixed(prefix); } module.exports.nextId = nextId; function triggerClickEvent(element) { var evt; var eventType = 'click'; if (document.createEvent) { try { // Chrome, Safari, Firefox evt = new MouseEvent(eventType, { view: window, bubbles: true, cancelable: true }); } catch (e) { // IE 11, PhantomJS (wat!) evt = document.createEvent('MouseEvent'); evt.initEvent(eventType, true, true); } return element.dispatchEvent(evt); } else { // Welcome IE evt = document.createEventObject(); return element.fireEvent('on' + eventType, evt); } } module.exports.triggerClickEvent = triggerClickEvent; },{"bpmn-js/lib/util/ModelUtil":216,"ids":414,"lodash/collection/forEach":422,"min-dom/lib/clear":107,"min-dom/lib/domify":110,"min-dom/lib/query":112}],6:[function(require,module,exports){ 'use strict'; var elementHelper = require('../helper/ElementHelper'); /** * A handler capable of creating a new element under a provided parent * and updating / creating a reference to it in one atomic action. * * @class * @constructor */ function CreateAndReferenceElementHandler(elementRegistry, bpmnFactory) { this._elementRegistry = elementRegistry; this._bpmnFactory = bpmnFactory; } CreateAndReferenceElementHandler.$inject = ['elementRegistry', 'bpmnFactory']; module.exports = CreateAndReferenceElementHandler; function ensureNotNull(prop, name) { if (!prop) { throw new Error(name + ' required'); } return prop; } ////// api ///////////////////////////////////////////// /** * Creates a new element under a provided parent and updates / creates a reference to it in * one atomic action. * * @method CreateAndReferenceElementHandler#execute * * @param {Object} context * @param {djs.model.Base} context.element which is the context for the reference * @param {moddle.referencingObject} context.referencingObject the object which creates the reference * @param {String} context.referenceProperty the property of the referencingObject which makes the reference * @param {moddle.newObject} context.newObject the new object to add * @param {moddle.newObjectContainer} context.newObjectContainer the container for the new object * * @returns {Array} the updated element */ CreateAndReferenceElementHandler.prototype.execute = function (context) { var referencingObject = ensureNotNull(context.referencingObject, 'referencingObject'), referenceProperty = ensureNotNull(context.referenceProperty, 'referenceProperty'), newObject = ensureNotNull(context.newObject, 'newObject'), newObjectContainer = ensureNotNull(context.newObjectContainer, 'newObjectContainer'), newObjectParent = ensureNotNull(context.newObjectParent, 'newObjectParent'), changed = [context.element]; // this will not change any diagram-js elements // create new object var referencedObject = elementHelper.createElement(newObject.type, newObject.properties, newObjectParent, this._bpmnFactory); context.referencedObject = referencedObject; // add to containing list newObjectContainer.push(referencedObject); // adjust reference attribute context.previousReference = referencingObject[referenceProperty]; referencingObject[referenceProperty] = referencedObject; context.changed = changed; // indicate changed on objects affected by the update return changed; }; /** * Reverts the update * * @method CreateAndReferenceElementHandler#revert * * @param {Object} context * * @returns {djs.mode.Base} the updated element */ CreateAndReferenceElementHandler.prototype.revert = function (context) { var referencingObject = context.referencingObject, referenceProperty = context.referenceProperty, previousReference = context.previousReference, referencedObject = context.referencedObject, newObjectContainer = context.newObjectContainer; // reset reference referencingObject.set(referenceProperty, previousReference); // remove new element newObjectContainer.splice(newObjectContainer.indexOf(referencedObject), 1); return context.changed; }; },{"../helper/ElementHelper":25}],7:[function(require,module,exports){ 'use strict'; var forEach = require('lodash/collection/forEach'); var elementHelper = require('../helper/ElementHelper'); /** * A handler that implements a BPMN 2.0 property update * for business objects which are not represented in the * diagram. * * This is useful in the context of the properties panel in * order to update child elements of elements visible in * the diagram. * * Example: perform an update of a specific event definition * of an intermediate event. * * @class * @constructor */ function CreateBusinessObjectListHandler(elementRegistry, bpmnFactory) { this._elementRegistry = elementRegistry; this._bpmnFactory = bpmnFactory; } CreateBusinessObjectListHandler.$inject = ['elementRegistry', 'bpmnFactory']; module.exports = CreateBusinessObjectListHandler; function ensureNotNull(prop, name) { if (!prop) { throw new Error(name + ' required'); } return prop; } function ensureList(prop, name) { if (!prop || Object.prototype.toString.call(prop) !== '[object Array]') { throw new Error(name + ' needs to be a list'); } return prop; } ////// api ///////////////////////////////////////////// /** * Creates a new element under a provided parent and updates / creates a reference to it in * one atomic action. * * @method CreateBusinessObjectListHandler#execute * * @param {Object} context * @param {djs.model.Base} context.element which is the context for the reference * @param {moddle.referencingObject} context.referencingObject the object which creates the reference * @param {String} context.referenceProperty the property of the referencingObject which makes the reference * @param {moddle.newObject} context.newObject the new object to add * @param {moddle.newObjectContainer} context.newObjectContainer the container for the new object * * @return {Array} the updated element */ CreateBusinessObjectListHandler.prototype.execute = function (context) { var currentObject = ensureNotNull(context.currentObject, 'currentObject'), propertyName = ensureNotNull(context.propertyName, 'propertyName'), newObjects = ensureList(context.newObjects, 'newObjects'), changed = [context.element]; // this will not change any diagram-js elements var childObjects = []; var self = this; // create new array of business objects forEach(newObjects, function (obj) { var element = elementHelper.createElement(obj.type, obj.properties, currentObject, self._bpmnFactory); childObjects.push(element); }); context.childObject = childObjects; // adjust array reference in the parent business object context.previousChilds = currentObject[propertyName]; currentObject[propertyName] = childObjects; context.changed = changed; // indicate changed on objects affected by the update return changed; }; /** * Reverts the update * * @method CreateBusinessObjectListHandler#revert * * @param {Object} context * * @return {djs.mode.Base} the updated element */ CreateBusinessObjectListHandler.prototype.revert = function (context) { var currentObject = context.currentObject, propertyName = context.propertyName, previousChilds = context.previousChilds; // remove new element currentObject.set(propertyName, previousChilds); return context.changed; }; },{"../helper/ElementHelper":25,"lodash/collection/forEach":422}],8:[function(require,module,exports){ 'use strict'; var forEach = require('lodash/collection/forEach'); /** * A handler that combines and executes multiple commands. * * All updates are bundled on the command stack and executed in one step. * This also makes it possible to revert the changes in one step. * * Example use case: remove the camunda:formKey attribute and in addition * add all form fields needed for the camunda:formData property. * * @class * @constructor */ function MultiCommandHandler(commandStack) { this._commandStack = commandStack; } MultiCommandHandler.$inject = ['commandStack']; module.exports = MultiCommandHandler; MultiCommandHandler.prototype.preExecute = function (context) { var commandStack = this._commandStack; forEach(context, function (command) { commandStack.execute(command.cmd, command.context); }); }; },{"lodash/collection/forEach":422}],9:[function(require,module,exports){ 'use strict'; var reduce = require('lodash/object/transform'), is = require('bpmn-js/lib/util/ModelUtil').is, keys = require('lodash/object/keys'), forEach = require('lodash/collection/forEach'); /** * A handler that implements a BPMN 2.0 property update * for business objects which are not represented in the * diagram. * * This is useful in the context of the properties panel in * order to update child elements of elements visible in * the diagram. * * Example: perform an update of a specific event definition * of an intermediate event. * * @class * @constructor */ function UpdateBusinessObjectHandler(elementRegistry) { this._elementRegistry = elementRegistry; } UpdateBusinessObjectHandler.$inject = ['elementRegistry']; module.exports = UpdateBusinessObjectHandler; /** * returns the root element */ function getRoot(businessObject) { var parent = businessObject; while (parent.$parent) { parent = parent.$parent; } return parent; } function getProperties(businessObject, propertyNames) { return reduce(propertyNames, function (result, key) { result[key] = businessObject.get(key); return result; }, {}); } function setProperties(businessObject, properties) { forEach(properties, function (value, key) { businessObject.set(key, value); }); } ////// api ///////////////////////////////////////////// /** * Updates a business object with a list of new properties * * @method UpdateBusinessObjectHandler#execute * * @param {Object} context * @param {djs.model.Base} context.element the element which has a child business object updated * @param {moddle.businessObject} context.businessObject the businessObject to update * @param {Object} context.properties a list of properties to set on the businessObject * * @return {Array} the updated element */ UpdateBusinessObjectHandler.prototype.execute = function (context) { var element = context.element, businessObject = context.businessObject, rootElements = getRoot(businessObject).rootElements, referenceType = context.referenceType, referenceProperty = context.referenceProperty, changed = [element]; // this will not change any diagram-js elements if (!element) { throw new Error('element required'); } if (!businessObject) { throw new Error('businessObject required'); } var properties = context.properties, oldProperties = context.oldProperties || getProperties(businessObject, keys(properties)); // check if there the update needs an external element for reference if (typeof referenceType !== 'undefined' && typeof referenceProperty !== 'undefined') { forEach(rootElements, function (rootElement) { if (is(rootElement, referenceType)) { if (rootElement.id === properties[referenceProperty]) { properties[referenceProperty] = rootElement; } } }); } // update properties setProperties(businessObject, properties); // store old values context.oldProperties = oldProperties; context.changed = changed; // indicate changed on objects affected by the update return changed; }; /** * Reverts the update * * @method UpdateBusinessObjectHandler#revert * * @param {Object} context * * @return {djs.mode.Base} the updated element */ UpdateBusinessObjectHandler.prototype.revert = function (context) { var oldProperties = context.oldProperties, businessObject = context.businessObject; // update properties setProperties(businessObject, oldProperties); return context.changed; }; },{"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/forEach":422,"lodash/object/keys":498,"lodash/object/transform":501}],10:[function(require,module,exports){ 'use strict'; var forEach = require('lodash/collection/forEach'); /** * A handler that implements a BPMN 2.0 property update * for business object lists which are not represented in the * diagram. * * This is useful in the context of the properties panel in * order to update child elements of elements visible in * the diagram. * * Example: perform an update of a specific event definition * of an intermediate event. * * @class * @constructor */ function UpdateBusinessObjectListHandler(elementRegistry, bpmnFactory) { this._elementRegistry = elementRegistry; this._bpmnFactory = bpmnFactory; } UpdateBusinessObjectListHandler.$inject = ['elementRegistry', 'bpmnFactory']; module.exports = UpdateBusinessObjectListHandler; function ensureNotNull(prop, name) { if (!prop) { throw new Error(name + 'required'); } return prop; } ////// api ///////////////////////////////////////////// /** * Updates a element under a provided parent. */ UpdateBusinessObjectListHandler.prototype.execute = function (context) { var currentObject = ensureNotNull(context.currentObject, 'currentObject'), propertyName = ensureNotNull(context.propertyName, 'propertyName'), updatedObjectList = context.updatedObjectList, objectsToRemove = context.objectsToRemove || [], objectsToAdd = context.objectsToAdd || [], changed = [context.element], // this will not change any diagram-js elements referencePropertyName; if (context.referencePropertyName) { referencePropertyName = context.referencePropertyName; } var objectList = currentObject[propertyName]; // adjust array reference in the parent business object context.previousList = currentObject[propertyName]; if (updatedObjectList) { currentObject[propertyName] = updatedObjectList; } else { var listCopy = []; // remove all objects which should be removed forEach(objectList, function (object) { if (objectsToRemove.indexOf(object) == -1) { listCopy.push(object); } }); // add all objects which should be added listCopy = listCopy.concat(objectsToAdd); // set property to new list if (listCopy.length > 0 || !referencePropertyName) { // as long as there are elements in the list update the list currentObject[propertyName] = listCopy; } else if (referencePropertyName) { // remove the list when it is empty var parentObject = currentObject.$parent; parentObject.set(referencePropertyName, undefined); } } context.changed = changed; // indicate changed on objects affected by the update return changed; }; /** * Reverts the update * * @method CreateBusinessObjectListHandler#revert * * @param {Object} context * * @return {djs.mode.Base} the updated element */ UpdateBusinessObjectListHandler.prototype.revert = function (context) { var currentObject = context.currentObject, propertyName = context.propertyName, previousList = context.previousList, parentObject = currentObject.$parent; if (context.referencePropertyName) { parentObject.set(context.referencePropertyName, currentObject); } // remove new element currentObject.set(propertyName, previousList); return context.changed; }; },{"lodash/collection/forEach":422}],11:[function(require,module,exports){ 'use strict'; var forEach = require('lodash/collection/forEach'); var HANDLERS = { 'properties-panel.update-businessobject': require('./UpdateBusinessObjectHandler'), 'properties-panel.create-and-reference': require('./CreateAndReferenceHandler'), 'properties-panel.create-businessobject-list': require('./CreateBusinessObjectListHandler'), 'properties-panel.update-businessobject-list': require('./UpdateBusinessObjectListHandler'), 'properties-panel.multi-command-executor': require('./MultiCommandHandler') }; function CommandInitializer(eventBus, commandStack) { eventBus.on('diagram.init', function () { forEach(HANDLERS, function (handler, id) { commandStack.registerHandler(id, handler); }); }); } CommandInitializer.$inject = ['eventBus', 'commandStack']; module.exports = { __init__: [CommandInitializer] }; },{"./CreateAndReferenceHandler":6,"./CreateBusinessObjectListHandler":7,"./MultiCommandHandler":8,"./UpdateBusinessObjectHandler":9,"./UpdateBusinessObjectListHandler":10,"lodash/collection/forEach":422}],12:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, cmdHelper = require('../helper/CmdHelper'); var entryFieldDescription = require('./EntryFieldDescription'); var checkbox = function checkbox(options, defaultParameters) { var resource = defaultParameters, label = options.label || resource.id, canBeDisabled = !!options.disabled && typeof options.disabled === 'function', canBeHidden = !!options.hidden && typeof options.hidden === 'function', description = options.description; resource.html = '' + ''; // add description below checkbox entry field if (description) { resource.html += entryFieldDescription(description); } resource.get = function (element) { var bo = getBusinessObject(element), res = {}; res[options.modelProperty] = bo.get(options.modelProperty); return res; }; resource.set = function (element, values) { var res = {}; res[options.modelProperty] = !!values[options.modelProperty]; return cmdHelper.updateProperties(element, res); }; if (typeof options.set === 'function') { resource.set = options.set; } if (typeof options.get === 'function') { resource.get = options.get; } if (canBeDisabled) { resource.isDisabled = function () { return options.disabled.apply(resource, arguments); }; } if (canBeHidden) { resource.isHidden = function () { return !options.hidden.apply(resource, arguments); }; } resource.cssClasses = ['bpp-checkbox']; return resource; }; module.exports = checkbox; },{"../helper/CmdHelper":24,"./EntryFieldDescription":15,"bpmn-js/lib/util/ModelUtil":216}],13:[function(require,module,exports){ 'use strict'; var assign = require('lodash/object/assign'), find = require('lodash/collection/find'); var domQuery = require('min-dom/lib/query'); var selectEntryFactory = require('./SelectEntryFactory'), entryFieldDescription = require('./EntryFieldDescription'); /** * The combo box is a special implementation of the select entry and adds the option 'custom' to the * select box. If 'custom' is selected, an additional text input field is shown which allows to define * a custom value. * * @param {Object} options * @param {string} options.id * @param {string} options.label * @param {Array} options.selectOptions list of name/value pairs * @param {string} options.modelProperty * @param {function} options.get * @param {function} options.set * @param {string} [options.customValue] custom select option value (default: 'custom') * @param {string} [options.customName] custom select option name visible in the select box (default: 'custom') * * @return {Object} */ var comboBox = function comboBox(options) { var selectOptions = options.selectOptions, modelProperty = options.modelProperty, customValue = options.customValue || 'custom', customName = options.customName || 'custom ' + modelProperty, description = options.description; // check if a value is not a built in value var isCustomValue = function isCustomValue(value) { if (typeof value[modelProperty] === 'undefined') { return false; } var isCustom = !find(selectOptions, function (option) { return value[modelProperty] === option.value; }); return isCustom; }; var comboOptions = assign({}, options); // true if the selected value in the select box is customValue comboOptions.showCustomInput = function (element, node) { var selectBox = domQuery('[data-entry="' + options.id + '"] select', node.parentNode); if (selectBox) { return selectBox.value === customValue; } return false; }; comboOptions.get = function (element, node) { var value = options.get(element, node); var modifiedValues = {}; if (!isCustomValue(value)) { modifiedValues[modelProperty] = value[modelProperty] || ''; return modifiedValues; } modifiedValues[modelProperty] = customValue; modifiedValues['custom-' + modelProperty] = value[modelProperty]; return modifiedValues; }; comboOptions.set = function (element, values, node) { var modifiedValues = {}; // if the custom select option has been selected // take the value from the text input field if (values[modelProperty] === customValue) { modifiedValues[modelProperty] = values['custom-' + modelProperty] || ''; } else if (options.emptyParameter && values[modelProperty] === '') { modifiedValues[modelProperty] = undefined; } else { modifiedValues[modelProperty] = values[modelProperty]; } return options.set(element, modifiedValues, node); }; comboOptions.selectOptions.push({ name: customName, value: customValue }); var comboBoxEntry = assign({}, selectEntryFactory(comboOptions, comboOptions)); comboBoxEntry.html += '
' + '' + '
'; // add description below combo box entry field if (description) { comboBoxEntry.html += entryFieldDescription(description); } return comboBoxEntry; }; module.exports = comboBox; },{"./EntryFieldDescription":15,"./SelectEntryFactory":18,"lodash/collection/find":421,"lodash/object/assign":496,"min-dom/lib/query":112}],14:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; // input entities var textInputField = require('./TextInputEntryFactory'), checkboxField = require('./CheckboxEntryFactory'), selectBoxField = require('./SelectEntryFactory'), comboBoxField = require('./ComboEntryFactory'), textBoxField = require('./TextBoxEntryFactory'), validationAwareTextInputField = require('./ValidationAwareTextInput'), tableField = require('./TableEntryFactory'), labelEntry = require('./LabelFactory'), link = require('./LinkEntryFactory'); var cmdHelper = require('../helper/CmdHelper'); // helpers //////////////////////////////////////// function ensureNotNull(prop) { if (!prop) { throw new Error(prop + ' must be set.'); } return prop; } /** * sets the default parameters which are needed to create an entry * * @param options * @returns {{id: *, description: (*|string), get: (*|Function), set: (*|Function), * validate: (*|Function), html: string}} */ var setDefaultParameters = function setDefaultParameters(options) { // default method to fetch the current value of the input field var defaultGet = function defaultGet(element) { var bo = getBusinessObject(element), res = {}, prop = ensureNotNull(options.modelProperty); res[prop] = bo.get(prop); return res; }; // default method to set a new value to the input field var defaultSet = function defaultSet(element, values) { var res = {}, prop = ensureNotNull(options.modelProperty); if (values[prop] !== '') { res[prop] = values[prop]; } else { res[prop] = undefined; } return cmdHelper.updateProperties(element, res); }; // default validation method var defaultValidate = function defaultValidate() { return {}; }; return { id: options.id, description: options.description || '', get: options.get || defaultGet, set: options.set || defaultSet, validate: options.validate || defaultValidate, html: '' }; }; function EntryFactory() {} /** * Generates an text input entry object for a property panel. * options are: * - id: id of the entry - String * * - description: description of the property - String * * - label: label for the input field - String * * - set: setter method - Function * * - get: getter method - Function * * - validate: validation mehtod - Function * * - modelProperty: name of the model property - String * * - buttonAction: Object which contains the following properties: - Object * ---- name: name of the [data-action] callback - String * ---- method: callback function for [data-action] - Function * * - buttonShow: Object which contains the following properties: - Object * ---- name: name of the [data-show] callback - String * ---- method: callback function for [data-show] - Function * * @param options * @returns the propertyPanel entry resource object */ EntryFactory.textField = function (options) { return textInputField(options, setDefaultParameters(options)); }; EntryFactory.validationAwareTextField = function (options) { return validationAwareTextInputField(options, setDefaultParameters(options)); }; /** * Generates a checkbox input entry object for a property panel. * options are: * - id: id of the entry - String * * - description: description of the property - String * * - label: label for the input field - String * * - set: setter method - Function * * - get: getter method - Function * * - validate: validation mehtod - Function * * - modelProperty: name of the model property - String * * @param options * @returns the propertyPanel entry resource object */ EntryFactory.checkbox = function (options) { return checkboxField(options, setDefaultParameters(options)); }; EntryFactory.textBox = function (options) { return textBoxField(options, setDefaultParameters(options)); }; EntryFactory.selectBox = function (options) { return selectBoxField(options, setDefaultParameters(options)); }; EntryFactory.comboBox = function (options) { return comboBoxField(options); }; EntryFactory.table = function (options) { return tableField(options); }; EntryFactory.label = function (options) { return labelEntry(options); }; EntryFactory.link = function (options) { return link(options); }; module.exports = EntryFactory; },{"../helper/CmdHelper":24,"./CheckboxEntryFactory":12,"./ComboEntryFactory":13,"./LabelFactory":16,"./LinkEntryFactory":17,"./SelectEntryFactory":18,"./TableEntryFactory":19,"./TextBoxEntryFactory":20,"./TextInputEntryFactory":21,"./ValidationAwareTextInput":22,"bpmn-js/lib/util/ModelUtil":216}],15:[function(require,module,exports){ 'use strict'; var MARKDOWN_LINK_REGEX = /\[([^\)]+)\]\(([^\]]+)\)/g; /** * Replace MarkDown Link Syntax with HTML Link Syntax * [myLink](http://www.myLink.de) -> myLink * * @param {String} value * * @return {String} */ function linkify(text) { return text.replace(MARKDOWN_LINK_REGEX, '$1'); } module.exports = function entryFieldDescription(description) { description = linkify(description); return '
' + description + '
'; }; },{}],16:[function(require,module,exports){ 'use strict'; /** * The label factory provides a label entry. For the label text * it expects either a string provided by the options.labelText * parameter or it could be generated programmatically using a * function passed as the options.get parameter. * * @param {Object} options * @param {string} options.id * @param {string} [options.labelText] * @param {Function} [options.get] * @param {Function} [options.showLabel] * @param {Boolean} [options.divider] adds a divider at the top of the label if true; default: false */ var label = function label(options) { return { id: options.id, html: '', get: function get(element, node) { if (typeof options.get === 'function') { return options.get(element, node); } return { label: options.labelText }; }, showLabel: function showLabel(element, node) { if (typeof options.showLabel === 'function') { return options.showLabel(element, node); } return true; } }; }; module.exports = label; },{}],17:[function(require,module,exports){ 'use strict'; var utils = require('../Utils'); var entryFieldDescription = require('./EntryFieldDescription'); var link = function link(options, defaultParameters) { var id = options.id, label = options.label || id, hideLink = options.hideLink, canBeHidden = typeof hideLink === 'function', getClickableElement = options.getClickableElement, description = options.description; var resource = { id: id }; resource.html = '' + label + ''; // add description below link entry field if (description) { resource.html += entryFieldDescription(description); } resource.linkSelected = function (element, node, event, scopeNode) { if (typeof getClickableElement === 'function') { var link = getClickableElement.apply(resource, [element, node, event, scopeNode]); link && utils.triggerClickEvent(link); } return false; }; if (canBeHidden) { resource.hideLink = function () { return !hideLink.apply(resource, arguments); }; } return resource; }; module.exports = link; },{"../Utils":5,"./EntryFieldDescription":15}],18:[function(require,module,exports){ 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var domify = require('min-dom/lib/domify'); var forEach = require('lodash/collection/forEach'); var entryFieldDescription = require('./EntryFieldDescription'); var isList = function isList(list) { return !(!list || Object.prototype.toString.call(list) !== '[object Array]'); }; var addEmptyParameter = function addEmptyParameter(list) { return list.concat([{ name: '', value: '' }]); }; var createOption = function createOption(option) { return ''; }; /** * @param {Object} options * @param {string} options.id * @param {string} [options.label] * @param {Array} options.selectOptions * @param {string} options.modelProperty * @param {boolean} options.emptyParameter * @param {function} options.disabled * @param {function} options.hidden * @param {Object} defaultParameters * * @return {Object} */ var selectbox = function selectbox(options, defaultParameters) { var resource = defaultParameters, label = options.label || resource.id, selectOptions = options.selectOptions || [{ name: '', value: '' }], modelProperty = options.modelProperty, emptyParameter = options.emptyParameter, canBeDisabled = !!options.disabled && typeof options.disabled === 'function', canBeHidden = !!options.hidden && typeof options.hidden === 'function', description = options.description; if (emptyParameter) { selectOptions = addEmptyParameter(selectOptions); } resource.html = '' + ''; // add description below select box entry field if (description && !_typeof(options.showCustomInput) === 'function') { resource.html += entryFieldDescription(description); } /** * Fill the select box options dynamically. * * Calls the defined function #selectOptions in the entry to get the * values for the options and set the value to the inputNode. * * @param {djs.model.Base} element * @param {HTMLElement} entryNode * @param {EntryDescriptor} inputNode * @param {Object} inputName * @param {Object} newValue */ resource.setControlValue = function (element, entryNode, inputNode, inputName, newValue) { if (typeof selectOptions === 'function') { var options = selectOptions(element, inputNode); if (options) { // remove existing options while (inputNode.firstChild) { inputNode.removeChild(inputNode.firstChild); } // add options forEach(options, function (option) { var template = domify(createOption(option)); inputNode.appendChild(template); }); } } // set select value if (newValue !== undefined) { inputNode.value = newValue; } }; if (canBeDisabled) { resource.isDisabled = function () { return options.disabled.apply(resource, arguments); }; } if (canBeHidden) { resource.isHidden = function () { return !options.hidden.apply(resource, arguments); }; } resource.cssClasses = ['bpp-dropdown']; return resource; }; module.exports = selectbox; },{"./EntryFieldDescription":15,"lodash/collection/forEach":422,"min-dom/lib/domify":110}],19:[function(require,module,exports){ 'use strict'; var cmdHelper = require('../helper/CmdHelper'); var domQuery = require('min-dom/lib/query'), domAttr = require('min-dom/lib/attr'), domClosest = require('min-dom/lib/closest'); var filter = require('lodash/collection/filter'), forEach = require('lodash/collection/forEach'), keys = require('lodash/object/keys'); var domify = require('min-dom/lib/domify'); var entryFieldDescription = require('./EntryFieldDescription'); var updateSelection = require('selection-update'); var TABLE_ROW_DIV_SNIPPET = '
'; var DELETE_ROW_BUTTON_SNIPPET = ''; function createInputRowTemplate(properties, canRemove) { var template = TABLE_ROW_DIV_SNIPPET; template += createInputTemplate(properties, canRemove); template += canRemove ? DELETE_ROW_BUTTON_SNIPPET : ''; template += '
'; return template; } function createInputTemplate(properties, canRemove) { var columns = properties.length; var template = ''; forEach(properties, function (prop) { template += ''; }); return template; } function createLabelRowTemplate(labels) { var template = TABLE_ROW_DIV_SNIPPET; template += createLabelTemplate(labels); template += ''; return template; } function createLabelTemplate(labels) { var columns = labels.length; var template = ''; forEach(labels, function (label) { template += ''; }); return template; } function pick(elements, properties) { return (elements || []).map(function (elem) { var newElement = {}; forEach(properties, function (prop) { newElement[prop] = elem[prop] || ''; }); return newElement; }); } function diff(element, node, values, oldValues, editable) { return filter(values, function (value, idx) { return !valueEqual(element, node, value, oldValues[idx], editable, idx); }); } function valueEqual(element, node, value, oldValue, editable, idx) { if (value && !oldValue) { return false; } var allKeys = keys(value).concat(keys(oldValue)); return allKeys.every(function (key) { var n = value[key] || undefined; var o = oldValue[key] || undefined; return !editable(element, node, key, idx) || n === o; }); } function getEntryNode(node) { return domClosest(node, '[data-entry]', true); } function getContainer(node) { return domQuery('div[data-list-entry-container]', node); } function getSelection(node) { return { start: node.selectionStart, end: node.selectionEnd }; } function setSelection(node, selection) { node.selectionStart = selection.start; node.selectionEnd = selection.end; } /** * @param {Object} options * @param {string} options.id * @param {string} options.description * @param {Array} options.modelProperties * @param {Array} options.labels * @param {Function} options.getElements - this callback function must return a list of business object items * @param {Function} options.removeElement * @param {Function} options.addElement * @param {Function} options.updateElement * @param {Function} options.editable * @param {Function} options.setControlValue * @param {Function} options.show * * @return {Object} */ module.exports = function (options) { var id = options.id, modelProperties = options.modelProperties, labels = options.labels, description = options.description; var labelRow = createLabelRowTemplate(labels); var getElements = options.getElements; var removeElement = options.removeElement, canRemove = typeof removeElement === 'function'; var addElement = options.addElement, canAdd = typeof addElement === 'function', addLabel = options.addLabel || 'Add Value'; var updateElement = options.updateElement, canUpdate = typeof updateElement === 'function'; var _editable = options.editable || function () { return true; }, setControlValue = options.setControlValue; var _show = options.show, canBeShown = typeof _show === 'function'; var elements = function elements(element, node) { return pick(getElements(element, node), modelProperties); }; var factory = { id: id, html: (canAdd ? '
' + '' + '' + '
' : '') + '
' + '
' + labelRow + '
' + '
' + '
' + '
' + ( // add description below table entry field description ? entryFieldDescription(description) : ''), get: function get(element, node) { var boElements = elements(element, node, this.__invalidValues); var invalidValues = this.__invalidValues; delete this.__invalidValues; forEach(invalidValues, function (value, idx) { var element = boElements[idx]; forEach(modelProperties, function (prop) { element[prop] = value[prop]; }); }); return boElements; }, set: function set(element, values, node) { var action = this.__action || {}; delete this.__action; if (action.id === 'delete-element') { return removeElement(element, node, action.idx); } else if (action.id === 'add-element') { return addElement(element, node); } else if (canUpdate) { var commands = [], valuesToValidate = values; if (typeof options.validate !== 'function') { valuesToValidate = diff(element, node, values, elements(element, node), _editable); } var self = this; forEach(valuesToValidate, function (value) { var validationError, idx = values.indexOf(value); if (typeof options.validate === 'function') { validationError = options.validate(element, value, node, idx); } if (!validationError) { var cmd = updateElement(element, value, node, idx); if (cmd) { commands.push(cmd); } } else { // cache invalid value in an object by index as key self.__invalidValues = self.__invalidValues || {}; self.__invalidValues[idx] = value; // execute a command, which does not do anything commands.push(cmdHelper.updateProperties(element, {})); } }); return commands; } }, createListEntryTemplate: function createListEntryTemplate(value, index, selectBox) { return createInputRowTemplate(modelProperties, canRemove); }, addElement: function addElement(element, node, event, scopeNode) { var template = domify(createInputRowTemplate(modelProperties, canRemove)); var container = getContainer(node); container.appendChild(template); this.__action = { id: 'add-element' }; return true; }, deleteElement: function deleteElement(element, node, event, scopeNode) { var container = getContainer(node); var rowToDelete = event.delegateTarget.parentNode; var idx = parseInt(domAttr(rowToDelete, 'data-index'), 10); container.removeChild(rowToDelete); this.__action = { id: 'delete-element', idx: idx }; return true; }, editable: function editable(element, rowNode, input, prop, value, idx) { var entryNode = domClosest(rowNode, '[data-entry]'); return _editable(element, entryNode, prop, idx); }, show: function show(element, entryNode, node, scopeNode) { entryNode = getEntryNode(entryNode); return _show(element, entryNode, node, scopeNode); }, showTable: function showTable(element, entryNode, node, scopeNode) { entryNode = getEntryNode(entryNode); var elems = elements(element, entryNode); return elems && elems.length && (!canBeShown || _show(element, entryNode, node, scopeNode)); }, validateListItem: function validateListItem(element, value, node, idx) { if (typeof options.validate === 'function') { return options.validate(element, value, node, idx); } } }; // Update/set the selection on the correct position. // It's the same code like for an input value in the PropertiesPanel.js. if (setControlValue) { factory.setControlValue = function (element, rowNode, input, prop, value, idx) { var entryNode = getEntryNode(rowNode); var isReadOnly = domAttr(input, 'readonly'); var oldValue = input.value; var selection; // prevents input fields from having the value 'undefined' if (value === undefined) { value = ''; } // when the attribute 'readonly' exists, ignore the comparison // with 'oldValue' and 'value' if (!!isReadOnly && oldValue === value) { return; } // update selection on undo/redo if (document.activeElement === input) { selection = updateSelection(getSelection(input), oldValue, value); } setControlValue(element, entryNode, input, prop, value, idx); if (selection) { setSelection(input, selection); } }; } return factory; }; },{"../helper/CmdHelper":24,"./EntryFieldDescription":15,"lodash/collection/filter":420,"lodash/collection/forEach":422,"lodash/object/keys":498,"min-dom/lib/attr":105,"min-dom/lib/closest":108,"min-dom/lib/domify":110,"min-dom/lib/query":112,"selection-update":533}],20:[function(require,module,exports){ 'use strict'; var entryFieldDescription = require('./EntryFieldDescription'); var textBox = function textBox(options, defaultParameters) { var resource = defaultParameters, label = options.label || resource.id, canBeShown = !!options.show && typeof options.show === 'function', description = options.description; resource.html = '' + '
' + '
' + '
'; // add description below text box entry field if (description) { resource.html += entryFieldDescription(description); } if (canBeShown) { resource.isShown = function () { return options.show.apply(resource, arguments); }; } resource.cssClasses = ['bpp-textbox']; return resource; }; module.exports = textBox; },{"./EntryFieldDescription":15}],21:[function(require,module,exports){ 'use strict'; var domQuery = require('min-dom/lib/query'); var entryFieldDescription = require('./EntryFieldDescription'); var textField = function textField(options, defaultParameters) { // Default action for the button next to the input-field var defaultButtonAction = function defaultButtonAction(element, inputNode) { var input = domQuery('input[name="' + options.modelProperty + '"]', inputNode); input.value = ''; return true; }; // default method to determine if the button should be visible var defaultButtonShow = function defaultButtonShow(element, inputNode) { var input = domQuery('input[name="' + options.modelProperty + '"]', inputNode); return input.value !== ''; }; var resource = defaultParameters, label = options.label || resource.id, dataValueLabel = options.dataValueLabel, buttonLabel = options.buttonLabel || 'X', actionName = typeof options.buttonAction != 'undefined' ? options.buttonAction.name : 'clear', actionMethod = typeof options.buttonAction != 'undefined' ? options.buttonAction.method : defaultButtonAction, showName = typeof options.buttonShow != 'undefined' ? options.buttonShow.name : 'canClear', showMethod = typeof options.buttonShow != 'undefined' ? options.buttonShow.method : defaultButtonShow, canBeDisabled = !!options.disabled && typeof options.disabled === 'function', canBeHidden = !!options.hidden && typeof options.hidden === 'function', description = options.description; resource.html = '' + '
' + '' + '' + '
'; // add description below text input entry field if (description) { resource.html += entryFieldDescription(description); } resource[actionName] = actionMethod; resource[showName] = showMethod; if (canBeDisabled) { resource.isDisabled = function () { return options.disabled.apply(resource, arguments); }; } if (canBeHidden) { resource.isHidden = function () { return !options.hidden.apply(resource, arguments); }; } resource.cssClasses = ['bpp-textfield']; return resource; }; module.exports = textField; },{"./EntryFieldDescription":15,"min-dom/lib/query":112}],22:[function(require,module,exports){ 'use strict'; var textField = require('./TextInputEntryFactory'); /** * This function is a wrapper around TextInputEntryFactory. * It adds functionality to cache an invalid value entered in the * text input, instead of setting it on the business object. */ var validationAwareTextField = function validationAwareTextField(options, defaultParameters) { var modelProperty = options.modelProperty; defaultParameters.get = function (element, node) { var value = this.__lastInvalidValue; delete this.__lastInvalidValue; var properties = {}; properties[modelProperty] = value !== undefined ? value : options.getProperty(element, node); return properties; }; defaultParameters.set = function (element, values, node) { var validationErrors = validate.apply(this, [element, values, node]), propertyValue = values[modelProperty]; // make sure we do not update the id if (validationErrors && validationErrors[modelProperty]) { this.__lastInvalidValue = propertyValue; return options.setProperty(element, {}, node); } else { var properties = {}; properties[modelProperty] = propertyValue; return options.setProperty(element, properties, node); } }; var validate = defaultParameters.validate = function (element, values, node) { var value = values[modelProperty] || this.__lastInvalidValue; var property = {}; property[modelProperty] = value; return options.validate(element, property, node); }; return textField(options, defaultParameters); }; module.exports = validationAwareTextField; },{"./TextInputEntryFactory":21}],23:[function(require,module,exports){ 'use strict'; var map = require('lodash/collection/map'); var extensionElementsHelper = require('./ExtensionElementsHelper'); /** * Returns true if the attribute 'camunda:asyncBefore' is set * to true. * * @param {ModdleElement} bo * * @return {boolean} a boolean value */ function isAsyncBefore(bo) { return !!(bo.get('camunda:asyncBefore') || bo.get('camunda:async')); } module.exports.isAsyncBefore = isAsyncBefore; /** * Returns true if the attribute 'camunda:asyncAfter' is set * to true. * * @param {ModdleElement} bo * * @return {boolean} a boolean value */ function isAsyncAfter(bo) { return !!bo.get('camunda:asyncAfter'); } module.exports.isAsyncAfter = isAsyncAfter; /** * Returns true if the attribute 'camunda:exclusive' is set * to true. * * @param {ModdleElement} bo * * @return {boolean} a boolean value */ function isExclusive(bo) { return !!bo.get('camunda:exclusive'); } module.exports.isExclusive = isExclusive; /** * Get first 'camunda:FailedJobRetryTimeCycle' from the business object. * * @param {ModdleElement} bo * * @return {Array} a list of 'camunda:FailedJobRetryTimeCycle' */ function getFailedJobRetryTimeCycle(bo) { return (extensionElementsHelper.getExtensionElements(bo, 'camunda:FailedJobRetryTimeCycle') || [])[0]; } module.exports.getFailedJobRetryTimeCycle = getFailedJobRetryTimeCycle; /** * Removes all existing 'camunda:FailedJobRetryTimeCycle' from the business object * * @param {ModdleElement} bo * * @return {Array} a list of 'camunda:FailedJobRetryTimeCycle' */ function removeFailedJobRetryTimeCycle(bo, element) { var retryTimeCycles = extensionElementsHelper.getExtensionElements(bo, 'camunda:FailedJobRetryTimeCycle'); return map(retryTimeCycles, function (cycle) { return extensionElementsHelper.removeEntry(bo, element, cycle); }); } module.exports.removeFailedJobRetryTimeCycle = removeFailedJobRetryTimeCycle; },{"./ExtensionElementsHelper":27,"lodash/collection/map":424}],24:[function(require,module,exports){ 'use strict'; var CmdHelper = {}; module.exports = CmdHelper; CmdHelper.updateProperties = function (element, properties) { return { cmd: 'element.updateProperties', context: { element: element, properties: properties } }; }; CmdHelper.updateBusinessObject = function (element, businessObject, newProperties) { return { cmd: 'properties-panel.update-businessobject', context: { element: element, businessObject: businessObject, properties: newProperties } }; }; CmdHelper.addElementsTolist = function (element, businessObject, listPropertyName, objectsToAdd) { return { cmd: 'properties-panel.update-businessobject-list', context: { element: element, currentObject: businessObject, propertyName: listPropertyName, objectsToAdd: objectsToAdd } }; }; CmdHelper.removeElementsFromList = function (element, businessObject, listPropertyName, referencePropertyName, objectsToRemove) { return { cmd: 'properties-panel.update-businessobject-list', context: { element: element, currentObject: businessObject, propertyName: listPropertyName, referencePropertyName: referencePropertyName, objectsToRemove: objectsToRemove } }; }; CmdHelper.addAndRemoveElementsFromList = function (element, businessObject, listPropertyName, referencePropertyName, objectsToAdd, objectsToRemove) { return { cmd: 'properties-panel.update-businessobject-list', context: { element: element, currentObject: businessObject, propertyName: listPropertyName, referencePropertyName: referencePropertyName, objectsToAdd: objectsToAdd, objectsToRemove: objectsToRemove } }; }; CmdHelper.setList = function (element, businessObject, listPropertyName, updatedObjectList) { return { cmd: 'properties-panel.update-businessobject-list', context: { element: element, currentObject: businessObject, propertyName: listPropertyName, updatedObjectList: updatedObjectList } }; }; },{}],25:[function(require,module,exports){ 'use strict'; var ElementHelper = {}; module.exports = ElementHelper; /** * Creates a new element and set the parent to it * * @method ElementHelper#createElement * * @param {String} elementType of the new element * @param {Object} properties of the new element in key-value pairs * @param {moddle.object} parent of the new element * @param {BpmnFactory} factory which creates the new element * * @returns {djs.model.Base} element which is created */ ElementHelper.createElement = function (elementType, properties, parent, factory) { var element = factory.create(elementType, properties); element.$parent = parent; return element; }; },{}],26:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, is = require('bpmn-js/lib/util/ModelUtil').is, forEach = require('lodash/collection/forEach'); var EventDefinitionHelper = {}; module.exports = EventDefinitionHelper; EventDefinitionHelper.getEventDefinition = function (element, eventType) { var bo = getBusinessObject(element), eventDefinition = null; if (bo.eventDefinitions) { forEach(bo.eventDefinitions, function (event) { if (is(event, eventType)) { eventDefinition = event; } }); } return eventDefinition; }; EventDefinitionHelper.getTimerEventDefinition = function (element) { return this.getEventDefinition(element, 'bpmn:TimerEventDefinition'); }; EventDefinitionHelper.getMessageEventDefinition = function (element) { return this.getEventDefinition(element, 'bpmn:MessageEventDefinition'); }; EventDefinitionHelper.getSignalEventDefinition = function (element) { return this.getEventDefinition(element, 'bpmn:SignalEventDefinition'); }; EventDefinitionHelper.getErrorEventDefinition = function (element) { return this.getEventDefinition(element, 'bpmn:ErrorEventDefinition'); }; EventDefinitionHelper.getEscalationEventDefinition = function (element) { return this.getEventDefinition(element, 'bpmn:EscalationEventDefinition'); }; EventDefinitionHelper.getCompensateEventDefinition = function (element) { return this.getEventDefinition(element, 'bpmn:CompensateEventDefinition'); }; EventDefinitionHelper.getLinkEventDefinition = function (element) { return this.getEventDefinition(element, 'bpmn:LinkEventDefinition'); }; EventDefinitionHelper.getConditionalEventDefinition = function (element) { return this.getEventDefinition(element, 'bpmn:ConditionalEventDefinition'); }; },{"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/forEach":422}],27:[function(require,module,exports){ 'use strict'; var cmdHelper = require('./CmdHelper'), elementHelper = require('./ElementHelper'); var is = require('bpmn-js/lib/util/ModelUtil').is; var ExtensionElementsHelper = {}; var getExtensionElements = function getExtensionElements(bo) { return bo.get('extensionElements'); }; ExtensionElementsHelper.getExtensionElements = function (bo, type) { var extensionElements = getExtensionElements(bo); if (typeof extensionElements !== 'undefined') { var extensionValues = extensionElements.get('values'); if (typeof extensionValues !== 'undefined') { var elements = extensionValues.filter(function (value) { return is(value, type); }); if (elements.length) { return elements; } } } }; ExtensionElementsHelper.addEntry = function (bo, element, entry, bpmnFactory) { var extensionElements = bo.get('extensionElements'); // if there is no extensionElements list, create one if (!extensionElements) { // TODO: Ask Daniel which operation costs more extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [entry] }, bo, bpmnFactory); return { extensionElements: extensionElements }; } else { // add new failedJobRetryExtensionElement to existing extensionElements list return cmdHelper.addElementsTolist(element, extensionElements, 'values', [entry]); } }; ExtensionElementsHelper.removeEntry = function (bo, element, entry) { var extensionElements = bo.get('extensionElements'); if (!extensionElements) { // return an empty command when there is no extensionElements list return {}; } return cmdHelper.removeElementsFromList(element, extensionElements, 'values', 'extensionElements', [entry]); }; module.exports = ExtensionElementsHelper; },{"./CmdHelper":24,"./ElementHelper":25,"bpmn-js/lib/util/ModelUtil":216}],28:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, getExtensionElements = require('./ExtensionElementsHelper').getExtensionElements; var FormHelper = {}; module.exports = FormHelper; /** * Return form data from business object or undefined if none exist * * @param {djs.model.Base} element * * @return {ModdleElement|undefined} formData */ FormHelper.getFormData = function (element) { var bo = getBusinessObject(element); var formData = getExtensionElements(bo, 'camunda:FormData'); if (typeof formData !== 'undefined') { return formData[0]; } }; /** * Return all form fields existing in the business object, and * an empty array if none exist. * * @param {djs.model.Base} element * * @return {Array} a list of form field objects */ FormHelper.getFormFields = function (element) { var formData = this.getFormData(element); if (typeof formData === 'undefined') { return []; } return formData.fields; }; /** * Get a form field from the business object at given index * * @param {djs.model.Base} element * @param {number} idx * * @return {ModdleElement} the form field */ FormHelper.getFormField = function (element, idx) { var formFields = this.getFormFields(element); return formFields[idx]; }; /** * Get all constraints for a specific form field from the business object * * @param {ModdleElement} formField * * @return {Array} a list of constraint objects */ FormHelper.getConstraints = function (formField) { if (formField && formField.validation && formField.validation.constraints) { return formField.validation.constraints; } return []; }; /** * Get all camunda:value objects for a specific form field from the business object * * @param {ModdleElement} formField * * @return {Array} a list of camunda:value objects */ FormHelper.getEnumValues = function (formField) { if (formField && formField.values) { return formField.values; } return []; }; },{"./ExtensionElementsHelper":27,"bpmn-js/lib/util/ModelUtil":216}],29:[function(require,module,exports){ 'use strict'; var ModelUtil = require('bpmn-js/lib/util/ModelUtil'), is = ModelUtil.is, getBusinessObject = ModelUtil.getBusinessObject; var eventDefinitionHelper = require('./EventDefinitionHelper'); var extensionsElementHelper = require('./ExtensionElementsHelper'); var ImplementationTypeHelper = {}; module.exports = ImplementationTypeHelper; /** * Returns 'true' if the given element is 'camunda:ServiceTaskLike' * * @param {djs.model.Base} element * * @return {boolean} a boolean value */ ImplementationTypeHelper.isServiceTaskLike = function (element) { return is(element, 'camunda:ServiceTaskLike'); }; /** * Returns 'true' if the given element is 'camunda:DmnCapable' * * @param {djs.model.Base} element * * @return {boolean} a boolean value */ ImplementationTypeHelper.isDmnCapable = function (element) { return is(element, 'camunda:DmnCapable'); }; /** * Returns 'true' if the given element is 'camunda:ExternalCapable' * * @param {djs.model.Base} element * * @return {boolean} a boolean value */ ImplementationTypeHelper.isExternalCapable = function (element) { return is(element, 'camunda:ExternalCapable'); }; /** * Returns 'true' if the given element is 'camunda:TaskListener' * * @param {djs.model.Base} element * * @return {boolean} a boolean value */ ImplementationTypeHelper.isTaskListener = function (element) { return is(element, 'camunda:TaskListener'); }; /** * Returns 'true' if the given element is 'camunda:ExecutionListener' * * @param {djs.model.Base} element * * @return {boolean} a boolean value */ ImplementationTypeHelper.isExecutionListener = function (element) { return is(element, 'camunda:ExecutionListener'); }; /** * Returns 'true' if the given element is 'camunda:ExecutionListener' or * 'camunda:TaskListener' * * @param {djs.model.Base} element * * @return {boolean} a boolean value */ ImplementationTypeHelper.isListener = function (element) { return this.isTaskListener(element) || this.isExecutionListener(element); }; /** * Returns 'true' if the given element is 'bpmn:SequenceFlow' * * @param {djs.model.Base} element * * @return {boolean} a boolean value */ ImplementationTypeHelper.isSequenceFlow = function (element) { return is(element, 'bpmn:SequenceFlow'); }; /** * Get a 'camunda:ServiceTaskLike' business object. * * If the given element is not a 'camunda:ServiceTaskLike', then 'false' * is returned. * * @param {djs.model.Base} element * * @return {ModdleElement} the 'camunda:ServiceTaskLike' business object */ ImplementationTypeHelper.getServiceTaskLikeBusinessObject = function (element) { if (is(element, 'bpmn:IntermediateThrowEvent') || is(element, 'bpmn:EndEvent')) { /** * change business object to 'messageEventDefinition' when * the element is a message intermediate throw event or message end event * because the camunda extensions (e.g. camunda:class) are in the message * event definition tag and not in the intermediate throw event or end event tag */ var messageEventDefinition = eventDefinitionHelper.getMessageEventDefinition(element); if (messageEventDefinition) { element = messageEventDefinition; } } return this.isServiceTaskLike(element) && getBusinessObject(element); }; /** * Returns the implementation type of the given element. * * Possible implementation types are: * - dmn * - connector * - external * - class * - expression * - delegateExpression * - script * - or undefined, when no matching implementation type is found * * @param {djs.model.Base} element * * @return {String} the implementation type */ ImplementationTypeHelper.getImplementationType = function (element) { var bo = this.getServiceTaskLikeBusinessObject(element); if (!bo) { if (this.isListener(element)) { bo = element; } else { return; } } if (this.isDmnCapable(bo)) { var decisionRef = bo.get('camunda:decisionRef'); if (typeof decisionRef !== 'undefined') { return 'dmn'; } } if (this.isServiceTaskLike(bo)) { var connectors = extensionsElementHelper.getExtensionElements(bo, 'camunda:Connector'); if (typeof connectors !== 'undefined') { return 'connector'; } } if (this.isExternalCapable(bo)) { var type = bo.get('camunda:type'); if (type === 'external') { return 'external'; } } var cls = bo.get('camunda:class'); if (typeof cls !== 'undefined') { return 'class'; } var expression = bo.get('camunda:expression'); if (typeof expression !== 'undefined') { return 'expression'; } var delegateExpression = bo.get('camunda:delegateExpression'); if (typeof delegateExpression !== 'undefined') { return 'delegateExpression'; } if (this.isListener(bo)) { var script = bo.get('script'); if (typeof script !== 'undefined') { return 'script'; } } }; },{"./EventDefinitionHelper":26,"./ExtensionElementsHelper":27,"bpmn-js/lib/util/ModelUtil":216}],30:[function(require,module,exports){ 'use strict'; var ModelUtil = require('bpmn-js/lib/util/ModelUtil'), is = ModelUtil.is, getBusinessObject = ModelUtil.getBusinessObject; var extensionElementsHelper = require('./ExtensionElementsHelper'), implementationTypeHelper = require('./ImplementationTypeHelper'); var InputOutputHelper = {}; module.exports = InputOutputHelper; function getElements(bo, type, prop) { var elems = extensionElementsHelper.getExtensionElements(bo, type) || []; return !prop ? elems : (elems[0] || {})[prop] || []; } function getParameters(element, prop, insideConnector) { var inputOutput = InputOutputHelper.getInputOutput(element, insideConnector); return inputOutput && inputOutput.get(prop) || []; } /** * Get a inputOutput from the business object * * @param {djs.model.Base} element * @param {boolean} insideConnector * * @return {ModdleElement} the inputOutput object */ InputOutputHelper.getInputOutput = function (element, insideConnector) { if (!insideConnector) { var bo = getBusinessObject(element); return (getElements(bo, 'camunda:InputOutput') || [])[0]; } var connector = this.getConnector(element); return connector && connector.get('inputOutput'); }; /** * Get a connector from the business object * * @param {djs.model.Base} element * * @return {ModdleElement} the connector object */ InputOutputHelper.getConnector = function (element) { var bo = implementationTypeHelper.getServiceTaskLikeBusinessObject(element); return bo && (getElements(bo, 'camunda:Connector') || [])[0]; }; /** * Return all input parameters existing in the business object, and * an empty array if none exist. * * @param {djs.model.Base} element * @param {boolean} insideConnector * * @return {Array} a list of input parameter objects */ InputOutputHelper.getInputParameters = function (element, insideConnector) { return getParameters.apply(this, [element, 'inputParameters', insideConnector]); }; /** * Return all output parameters existing in the business object, and * an empty array if none exist. * * @param {djs.model.Base} element * @param {boolean} insideConnector * * @return {Array} a list of output parameter objects */ InputOutputHelper.getOutputParameters = function (element, insideConnector) { return getParameters.apply(this, [element, 'outputParameters', insideConnector]); }; /** * Get a input parameter from the business object at given index * * @param {djs.model.Base} element * @param {boolean} insideConnector * @param {number} idx * * @return {ModdleElement} input parameter */ InputOutputHelper.getInputParameter = function (element, insideConnector, idx) { return this.getInputParameters(element, insideConnector)[idx]; }; /** * Get a output parameter from the business object at given index * * @param {djs.model.Base} element * @param {boolean} insideConnector * @param {number} idx * * @return {ModdleElement} output parameter */ InputOutputHelper.getOutputParameter = function (element, insideConnector, idx) { return this.getOutputParameters(element, insideConnector)[idx]; }; /** * Returns 'true' if the given element supports inputOutput * * @param {djs.model.Base} element * @param {boolean} insideConnector * * @return {boolean} a boolean value */ InputOutputHelper.isInputOutputSupported = function (element, insideConnector) { var bo = getBusinessObject(element); return insideConnector || is(bo, 'bpmn:FlowNode') && !is(bo, 'bpmn:StartEvent') && !is(bo, 'bpmn:BoundaryEvent') && !(is(bo, 'bpmn:SubProcess') && bo.get('triggeredByEvent')); }; /** * Returns 'true' if the given element supports output parameters * * @param {djs.model.Base} element * @param {boolean} insideConnector * * @return {boolean} a boolean value */ InputOutputHelper.areOutputParametersSupported = function (element, insideConnector) { var bo = getBusinessObject(element); return insideConnector || !is(bo, 'bpmn:EndEvent') && !bo.loopCharacteristics; }; },{"./ExtensionElementsHelper":27,"./ImplementationTypeHelper":29,"bpmn-js/lib/util/ModelUtil":216}],31:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, cmdHelper = require('./CmdHelper'); var ParticipantHelper = {}; module.exports = ParticipantHelper; ParticipantHelper.modifyProcessBusinessObject = function (element, property, values) { if (!is(element, 'bpmn:Participant')) { return {}; } var bo = getBusinessObject(element).get('processRef'), properties = {}; properties[property] = values[property]; return cmdHelper.updateBusinessObject(element, bo, properties); }; ParticipantHelper.getProcessBusinessObject = function (element, propertyName) { if (!is(element, 'bpmn:Participant')) { return {}; } var bo = getBusinessObject(element).get('processRef'), properties = {}; properties[propertyName] = bo.get(propertyName); return properties; }; },{"./CmdHelper":24,"bpmn-js/lib/util/ModelUtil":216}],32:[function(require,module,exports){ 'use strict'; module.exports = { __depends__: [require('./cmd'), require('diagram-js/lib/i18n/translate')], __init__: ['propertiesPanel'], propertiesPanel: ['type', require('./PropertiesPanel')] }; },{"./PropertiesPanel":4,"./cmd":11,"diagram-js/lib/i18n/translate":376}],33:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../factory/EntryFactory'), cmdHelper = require('../../../helper/CmdHelper'); var ModelUtil = require('bpmn-js/lib/util/ModelUtil'), is = ModelUtil.is, getBusinessObject = ModelUtil.getBusinessObject; module.exports = function (group, element, bpmnFactory, translate) { var getValue = function getValue(businessObject) { return function (element) { var documentations = businessObject && businessObject.get('documentation'), text = documentations && documentations.length > 0 ? documentations[0].text : ''; return { documentation: text }; }; }; var setValue = function setValue(businessObject) { return function (element, values) { var newObjectList = []; if (typeof values.documentation !== 'undefined' && values.documentation !== '') { newObjectList.push(bpmnFactory.create('bpmn:Documentation', { text: values.documentation })); } return cmdHelper.setList(element, businessObject, 'documentation', newObjectList); }; }; // Element Documentation var elementDocuEntry = entryFactory.textBox({ id: 'documentation', label: translate('Element Documentation'), modelProperty: 'documentation' }); elementDocuEntry.set = setValue(getBusinessObject(element)); elementDocuEntry.get = getValue(getBusinessObject(element)); group.entries.push(elementDocuEntry); var processRef; // Process Documentation when having a Collaboration Diagram if (is(element, 'bpmn:Participant')) { processRef = getBusinessObject(element).processRef; // do not show for collapsed Pools/Participants if (processRef) { var processDocuEntry = entryFactory.textBox({ id: 'process-documentation', label: translate('Process Documentation'), modelProperty: 'documentation' }); processDocuEntry.set = setValue(processRef); processDocuEntry.get = getValue(processRef); group.entries.push(processDocuEntry); } } }; },{"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"bpmn-js/lib/util/ModelUtil":216}],34:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, isAny = require('bpmn-js/lib/features/modeling/util/ModelingUtil').isAny, isEventSubProcess = require('bpmn-js/lib/util/DiUtil').isEventSubProcess, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, eventDefinitionHelper = require('../../../helper/EventDefinitionHelper'); var forEach = require('lodash/collection/forEach'); var message = require('./implementation/MessageEventDefinition'), signal = require('./implementation/SignalEventDefinition'), error = require('./implementation/ErrorEventDefinition'), escalation = require('./implementation/EscalationEventDefinition'), timer = require('./implementation/TimerEventDefinition'), compensation = require('./implementation/CompensateEventDefinition'), condition = require('./implementation/ConditionalEventDefinition'); module.exports = function (group, element, bpmnFactory, elementRegistry, translate) { var events = ['bpmn:StartEvent', 'bpmn:EndEvent', 'bpmn:IntermediateThrowEvent', 'bpmn:BoundaryEvent', 'bpmn:IntermediateCatchEvent']; // Message and Signal Event Definition forEach(events, function (event) { if (is(element, event)) { var messageEventDefinition = eventDefinitionHelper.getMessageEventDefinition(element), signalEventDefinition = eventDefinitionHelper.getSignalEventDefinition(element); if (messageEventDefinition) { message(group, element, bpmnFactory, messageEventDefinition); } if (signalEventDefinition) { signal(group, element, bpmnFactory, signalEventDefinition); } } }); // Special Case: Receive Task if (is(element, 'bpmn:ReceiveTask')) { message(group, element, bpmnFactory, getBusinessObject(element)); } // Error Event Definition var errorEvents = ['bpmn:StartEvent', 'bpmn:BoundaryEvent', 'bpmn:EndEvent']; forEach(errorEvents, function (event) { if (is(element, event)) { var errorEventDefinition = eventDefinitionHelper.getErrorEventDefinition(element); if (errorEventDefinition) { var isCatchingErrorEvent = is(element, 'bpmn:StartEvent') || is(element, 'bpmn:BoundaryEvent'); var showErrorCodeVariable = isCatchingErrorEvent, showErrorMessageVariable = isCatchingErrorEvent; error(group, element, bpmnFactory, errorEventDefinition, showErrorCodeVariable, showErrorMessageVariable); } } }); // Escalation Event Definition var escalationEvents = ['bpmn:StartEvent', 'bpmn:BoundaryEvent', 'bpmn:IntermediateThrowEvent', 'bpmn:EndEvent']; forEach(escalationEvents, function (event) { if (is(element, event)) { var showEscalationCodeVariable = is(element, 'bpmn:StartEvent') || is(element, 'bpmn:BoundaryEvent'); // get business object var escalationEventDefinition = eventDefinitionHelper.getEscalationEventDefinition(element); if (escalationEventDefinition) { escalation(group, element, bpmnFactory, escalationEventDefinition, showEscalationCodeVariable); } } }); // Timer Event Definition var timerEvents = ['bpmn:StartEvent', 'bpmn:BoundaryEvent', 'bpmn:IntermediateCatchEvent']; forEach(timerEvents, function (event) { if (is(element, event)) { // get business object var timerEventDefinition = eventDefinitionHelper.getTimerEventDefinition(element); if (timerEventDefinition) { timer(group, element, bpmnFactory, timerEventDefinition); } } }); // Compensate Event Definition var compensationEvents = ['bpmn:EndEvent', 'bpmn:IntermediateThrowEvent']; forEach(compensationEvents, function (event) { if (is(element, event)) { // get business object var compensateEventDefinition = eventDefinitionHelper.getCompensateEventDefinition(element); if (compensateEventDefinition) { compensation(group, element, bpmnFactory, compensateEventDefinition, elementRegistry); } } }); // Conditional Event Defintion var conditionalEvents = ['bpmn:BoundaryEvent', 'bpmn:IntermediateThrowEvent', 'bpmn:IntermediateCatchEvent']; if (isAny(element, conditionalEvents) || is(element, 'bpmn:StartEvent') && isEventSubProcess(element.parent)) { // get business object var conditionalEventDefinition = eventDefinitionHelper.getConditionalEventDefinition(element); if (conditionalEventDefinition) { condition(group, element, bpmnFactory, conditionalEventDefinition, elementRegistry); } } }; },{"../../../helper/EventDefinitionHelper":26,"./implementation/CompensateEventDefinition":40,"./implementation/ConditionalEventDefinition":41,"./implementation/ErrorEventDefinition":43,"./implementation/EscalationEventDefinition":44,"./implementation/MessageEventDefinition":46,"./implementation/SignalEventDefinition":48,"./implementation/TimerEventDefinition":49,"bpmn-js/lib/features/modeling/util/ModelingUtil":189,"bpmn-js/lib/util/DiUtil":214,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/forEach":422}],35:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var entryFactory = require('../../../factory/EntryFactory'); var participantHelper = require('../../../helper/ParticipantHelper'); module.exports = function (group, element, translate) { var bo = getBusinessObject(element); if (!bo) { return; } if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && bo.get('processRef')) { var executableEntry = entryFactory.checkbox({ id: 'process-is-executable', label: translate('Executable'), modelProperty: 'isExecutable' }); // in participants we have to change the default behavior of set and get if (is(element, 'bpmn:Participant')) { executableEntry.get = function (element) { return participantHelper.getProcessBusinessObject(element, 'isExecutable'); }; executableEntry.set = function (element, values) { return participantHelper.modifyProcessBusinessObject(element, 'isExecutable', values); }; } group.entries.push(executableEntry); } }; },{"../../../factory/EntryFactory":14,"../../../helper/ParticipantHelper":31,"bpmn-js/lib/util/ModelUtil":216}],36:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../factory/EntryFactory'), getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, utils = require('../../../Utils'), cmdHelper = require('../../../helper/CmdHelper'); module.exports = function (group, element, translate) { // Id group.entries.push(entryFactory.validationAwareTextField({ id: 'id', label: translate('Id'), modelProperty: 'id', getProperty: function getProperty(element) { return getBusinessObject(element).id; }, setProperty: function setProperty(element, properties) { element = element.labelTarget || element; return cmdHelper.updateProperties(element, properties); }, validate: function validate(element, values) { var idValue = values.id; var bo = getBusinessObject(element); var idError = utils.isIdValid(bo, idValue); return idError ? { id: idError } : {}; } })); }; },{"../../../Utils":5,"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"bpmn-js/lib/util/ModelUtil":216}],37:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, entryFactory = require('../../../factory/EntryFactory'), cmdHelper = require('../../../helper/CmdHelper'); var forEach = require('lodash/collection/forEach'); function getLinkEventDefinition(element) { var bo = getBusinessObject(element); var linkEventDefinition = null; if (bo.eventDefinitions) { forEach(bo.eventDefinitions, function (eventDefinition) { if (is(eventDefinition, 'bpmn:LinkEventDefinition')) { linkEventDefinition = eventDefinition; } }); } return linkEventDefinition; } module.exports = function (group, element, translate) { var linkEvents = ['bpmn:IntermediateThrowEvent', 'bpmn:IntermediateCatchEvent']; forEach(linkEvents, function (event) { if (is(element, event)) { var linkEventDefinition = getLinkEventDefinition(element); if (linkEventDefinition) { var entry = entryFactory.textField({ id: 'link-event', label: translate('Link Name'), modelProperty: 'link-name' }); entry.get = function () { return { 'link-name': linkEventDefinition.get('name') }; }; entry.set = function (element, values) { var newProperties = { name: values['link-name'] }; return cmdHelper.updateBusinessObject(element, linkEventDefinition, newProperties); }; group.entries.push(entry); } } }); }; },{"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/forEach":422}],38:[function(require,module,exports){ 'use strict'; var nameEntryFactory = require('./implementation/Name'), is = require('bpmn-js/lib/util/ModelUtil').is; module.exports = function (group, element, translate) { if (!is(element, 'bpmn:Collaboration')) { var options; if (is(element, 'bpmn:TextAnnotation')) { options = { modelProperty: 'text' }; } // name group.entries = group.entries.concat(nameEntryFactory(element, options, translate)); } }; },{"./implementation/Name":47,"bpmn-js/lib/util/ModelUtil":216}],39:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, entryFactory = require('../../../factory/EntryFactory'), participantHelper = require('../../../helper/ParticipantHelper'), getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, nameEntryFactory = require('./implementation/Name'), utils = require('../../../Utils'); module.exports = function (group, element, translate) { var businessObject = getBusinessObject(element); if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) { /** * processId */ if (is(element, 'bpmn:Participant')) { var idEntry = entryFactory.validationAwareTextField({ id: 'process-id', label: translate('Process Id'), modelProperty: 'processId' }); // in participants we have to change the default behavior of set and get idEntry.get = function (element) { var properties = participantHelper.getProcessBusinessObject(element, 'id'); return { processId: properties.id }; }; idEntry.set = function (element, values) { return participantHelper.modifyProcessBusinessObject(element, 'id', { id: values.processId }); }; idEntry.validate = function (element, values) { var idValue = values.processId; var bo = getBusinessObject(element); var processIdError = utils.isIdValid(bo.processRef, idValue); return processIdError ? { processId: processIdError } : {}; }; group.entries.push(idEntry); /** * process name */ var processNameEntry = nameEntryFactory(element, { id: 'process-name', label: translate('Process Name') })[0]; // in participants we have to change the default behavior of set and get processNameEntry.get = function (element) { return participantHelper.getProcessBusinessObject(element, 'name'); }; processNameEntry.set = function (element, values) { return participantHelper.modifyProcessBusinessObject(element, 'name', values); }; group.entries.push(processNameEntry); } } }; },{"../../../Utils":5,"../../../factory/EntryFactory":14,"../../../helper/ParticipantHelper":31,"./implementation/Name":47,"bpmn-js/lib/util/ModelUtil":216}],40:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'); var cmdHelper = require('../../../../helper/CmdHelper'), eventDefinitionHelper = require('../../../../helper/EventDefinitionHelper'), utils = require('../../../../Utils'); var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, is = require('bpmn-js/lib/util/ModelUtil').is; var forEach = require('lodash/collection/forEach'), find = require('lodash/collection/find'), filter = require('lodash/collection/filter'); function getContainedActivities(element) { return getFlowElements(element, 'bpmn:Activity'); } function getContainedBoundaryEvents(element) { return getFlowElements(element, 'bpmn:BoundaryEvent'); } function getFlowElements(element, type) { return utils.filterElementsByType(element.flowElements, type); } function isCompensationEventAttachedToActivity(activity, boundaryEvents) { var activityId = activity.id; var boundaryEvent = find(boundaryEvents, function (boundaryEvent) { var compensateEventDefinition = eventDefinitionHelper.getCompensateEventDefinition(boundaryEvent); var attachedToRef = boundaryEvent.attachedToRef; return compensateEventDefinition && attachedToRef && attachedToRef.id === activityId; }); return !!boundaryEvent; } // subprocess: only when it is not triggeredByEvent // activity: only when it attach a compensation boundary event // callActivity: no limitation function canActivityBeCompensated(activity, boundaryEvents) { return is(activity, 'bpmn:SubProcess') && !activity.triggeredByEvent || is(activity, 'bpmn:CallActivity') || isCompensationEventAttachedToActivity(activity, boundaryEvents); } function getActivitiesForCompensation(element) { var boundaryEvents = getContainedBoundaryEvents(element); return filter(getContainedActivities(element), function (activity) { return canActivityBeCompensated(activity, boundaryEvents); }); } function getActivitiesForActivityRef(element) { var bo = getBusinessObject(element); var parent = bo.$parent; var activitiesForActivityRef = getActivitiesForCompensation(parent); // if throwing compensation event is in an event sub process: // get also all activities outside of the event sub process if (is(parent, 'bpmn:SubProcess') && parent.triggeredByEvent) { parent = parent.$parent; if (parent) { activitiesForActivityRef = activitiesForActivityRef.concat(getActivitiesForCompensation(parent)); } } return activitiesForActivityRef; } function createActivityRefOptions(element) { var options = [{ value: '' }]; var activities = getActivitiesForActivityRef(element); forEach(activities, function (activity) { var activityId = activity.id; var name = (activity.name ? activity.name + ' ' : '') + '(id=' + activityId + ')'; options.push({ value: activityId, name: name }); }); return options; } module.exports = function (group, element, bpmnFactory, compensateEventDefinition, elementRegistry) { group.entries.push(entryFactory.checkbox({ id: 'wait-for-completion', label: 'Wait for Completion', modelProperty: 'waitForCompletion', get: function get(element, node) { return { waitForCompletion: compensateEventDefinition.waitForCompletion }; }, set: function set(element, values) { values.waitForCompletion = values.waitForCompletion || false; return cmdHelper.updateBusinessObject(element, compensateEventDefinition, values); } })); group.entries.push(entryFactory.selectBox({ id: 'activity-ref', label: 'Activity Ref', selectOptions: createActivityRefOptions(element), modelProperty: 'activityRef', get: function get(element, node) { var activityRef = compensateEventDefinition.activityRef; activityRef = activityRef && activityRef.id; return { activityRef: activityRef || '' }; }, set: function set(element, values) { var activityRef = values.activityRef || undefined; activityRef = activityRef && getBusinessObject(elementRegistry.get(activityRef)); return cmdHelper.updateBusinessObject(element, compensateEventDefinition, { activityRef: activityRef }); } })); }; },{"../../../../Utils":5,"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/EventDefinitionHelper":26,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/filter":420,"lodash/collection/find":421,"lodash/collection/forEach":422}],41:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'), elementHelper = require('../../../../helper/ElementHelper'), cmdHelper = require('../../../../helper/CmdHelper'); function createFormalExpression(parent, body, bpmnFactory) { body = body || undefined; return elementHelper.createElement('bpmn:FormalExpression', { body: body }, parent, bpmnFactory); } module.exports = function (group, element, bpmnFactory, conditionalEventDefinition) { var getValue = function getValue(modelProperty) { return function (element) { var modelPropertyValue = conditionalEventDefinition.get('camunda:' + modelProperty); var value = {}; value[modelProperty] = modelPropertyValue; return value; }; }; var setValue = function setValue(modelProperty) { return function (element, values) { var props = {}; props['camunda:' + modelProperty] = values[modelProperty] || undefined; return cmdHelper.updateBusinessObject(element, conditionalEventDefinition, props); }; }; group.entries.push(entryFactory.textField({ id: 'condition', label: 'Condition', modelProperty: 'condition', get: function get(element) { var condition = conditionalEventDefinition.get('condition'), body = condition && condition.get('body'); return { condition: body || '' }; }, set: function set(element, values) { var condition = conditionalEventDefinition.get('condition'); // remove condition expression from the business object when text field is empty if (values.condition === '') { return cmdHelper.updateBusinessObject(element, conditionalEventDefinition, { condition: undefined }); } // if no condition expression is set yet, create one if (!condition) { condition = createFormalExpression(conditionalEventDefinition, values.condition, bpmnFactory); return cmdHelper.updateBusinessObject(element, conditionalEventDefinition, { condition: condition }); // if a condition expression and a text field value exists, update business object } else { return cmdHelper.updateBusinessObject(element, condition, { body: values.condition || undefined }); } }, validate: function validate(element, values) { if (values['condition'] === '') { return { condition: 'Must provide a value' }; } } })); group.entries.push(entryFactory.textField({ id: 'variableName', label: 'Variable Name', modelProperty: 'variableName', get: getValue('variableName'), set: setValue('variableName') })); group.entries.push(entryFactory.textField({ id: 'variableEvent', label: 'Variable Event', description: 'Specify more than one variable change event as a comma separated list.', modelProperty: 'variableEvent', get: getValue('variableEvent'), set: setValue('variableEvent') })); }; },{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25}],42:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'); var cmdHelper = require('../../../../helper/CmdHelper'); /** * Create an entry to modify a property of an element which * is referenced by a event definition. * * @param {djs.model.Base} element * @param {ModdleElement} definition * @param {BpmnFactory} bpmnFactory * @param {Object} options * @param {string} options.id the id of the entry * @param {string} options.label the label of the entry * @param {string} options.referenceProperty the name of referencing property * @param {string} options.modelProperty the name of property to modify * @param {string} options.shouldValidate a flag indicate whether to validate or not * * @return {Array} return an array containing the entries */ module.exports = function (element, definition, bpmnFactory, options) { var id = options.id || 'element-property'; var label = options.label; var referenceProperty = options.referenceProperty; var modelProperty = options.modelProperty || 'name'; var shouldValidate = options.shouldValidate || false; var entry = entryFactory.textField({ id: id, label: label, modelProperty: modelProperty, get: function get(element, node) { var reference = definition.get(referenceProperty); var props = {}; props[modelProperty] = reference && reference.get(modelProperty); return props; }, set: function set(element, values, node) { var reference = definition.get(referenceProperty); var props = {}; props[modelProperty] = values[modelProperty] || undefined; return cmdHelper.updateBusinessObject(element, reference, props); }, hidden: function hidden(element, node) { return !definition.get(referenceProperty); } }); if (shouldValidate) { entry.validate = function (element, values, node) { var reference = definition.get(referenceProperty); if (reference && !values[modelProperty]) { var validationErrors = {}; validationErrors[modelProperty] = 'Must provide a value'; return validationErrors; } }; } return [entry]; }; },{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24}],43:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'), cmdHelper = require('../../../../helper/CmdHelper'); var eventDefinitionReference = require('./EventDefinitionReference'), elementReferenceProperty = require('./ElementReferenceProperty'); module.exports = function (group, element, bpmnFactory, errorEventDefinition, showErrorCodeVariable, showErrorMessageVariable) { var getValue = function getValue(modelProperty) { return function (element) { var modelPropertyValue = errorEventDefinition.get('camunda:' + modelProperty); var value = {}; value[modelProperty] = modelPropertyValue; return value; }; }; var setValue = function setValue(modelProperty) { return function (element, values) { var props = {}; props['camunda:' + modelProperty] = values[modelProperty] || undefined; return cmdHelper.updateBusinessObject(element, errorEventDefinition, props); }; }; group.entries = group.entries.concat(eventDefinitionReference(element, errorEventDefinition, bpmnFactory, { label: 'Error', elementName: 'error', elementType: 'bpmn:Error', referenceProperty: 'errorRef', newElementIdPrefix: 'Error_' })); group.entries = group.entries.concat(elementReferenceProperty(element, errorEventDefinition, bpmnFactory, { id: 'error-element-name', label: 'Error Name', referenceProperty: 'errorRef', modelProperty: 'name', shouldValidate: true })); group.entries = group.entries.concat(elementReferenceProperty(element, errorEventDefinition, bpmnFactory, { id: 'error-element-code', label: 'Error Code', referenceProperty: 'errorRef', modelProperty: 'errorCode' })); if (showErrorCodeVariable) { group.entries.push(entryFactory.textField({ id: 'errorCodeVariable', label: 'Error Code Variable', modelProperty: 'errorCodeVariable', get: getValue('errorCodeVariable'), set: setValue('errorCodeVariable') })); } if (showErrorMessageVariable) { group.entries.push(entryFactory.textField({ id: 'errorMessageVariable', label: 'Error Message Variable', modelProperty: 'errorMessageVariable', get: getValue('errorMessageVariable'), set: setValue('errorMessageVariable') })); } }; },{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"./ElementReferenceProperty":42,"./EventDefinitionReference":45}],44:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'), cmdHelper = require('../../../../helper/CmdHelper'); var eventDefinitionReference = require('./EventDefinitionReference'), elementReferenceProperty = require('./ElementReferenceProperty'); module.exports = function (group, element, bpmnFactory, escalationEventDefinition, showEscalationCodeVariable) { group.entries = group.entries.concat(eventDefinitionReference(element, escalationEventDefinition, bpmnFactory, { label: 'Escalation', elementName: 'escalation', elementType: 'bpmn:Escalation', referenceProperty: 'escalationRef', newElementIdPrefix: 'Escalation_' })); group.entries = group.entries.concat(elementReferenceProperty(element, escalationEventDefinition, bpmnFactory, { id: 'escalation-element-name', label: 'Escalation Name', referenceProperty: 'escalationRef', modelProperty: 'name', shouldValidate: true })); group.entries = group.entries.concat(elementReferenceProperty(element, escalationEventDefinition, bpmnFactory, { id: 'escalation-element-code', label: 'Escalation Code', referenceProperty: 'escalationRef', modelProperty: 'escalationCode' })); if (showEscalationCodeVariable) { group.entries.push(entryFactory.textField({ id: 'escalationCodeVariable', label: 'Escalation Code Variable', modelProperty: 'escalationCodeVariable', get: function get(element) { var codeVariable = escalationEventDefinition.get('camunda:escalationCodeVariable'); return { escalationCodeVariable: codeVariable }; }, set: function set(element, values) { return cmdHelper.updateBusinessObject(element, escalationEventDefinition, { 'camunda:escalationCodeVariable': values.escalationCodeVariable || undefined }); } })); } }; },{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"./ElementReferenceProperty":42,"./EventDefinitionReference":45}],45:[function(require,module,exports){ 'use strict'; var cmdHelper = require('../../../../helper/CmdHelper'); var domQuery = require('min-dom/lib/query'), domify = require('min-dom/lib/domify'), domAttr = require('min-dom/lib/attr'); var forEach = require('lodash/collection/forEach'), find = require('lodash/collection/find'); var elementHelper = require('../../../../helper/ElementHelper'); var utils = require('../../../../Utils'); var selector = 'select[name=selectedElement]'; /** * Get select box containing all elements. * * @param {DOMElement} node * * @return {DOMElement} the select box */ function getSelectBox(node) { return domQuery(selector, node.parentElement); } /** * Find element by given id. * * @param {ModdleElement} eventDefinition * * @return {ModdleElement} an element */ function findElementById(eventDefinition, type, id) { var elements = utils.findRootElementsByType(eventDefinition, type); return find(elements, function (element) { return element.id === id; }); } /** * Create an entry to modify the reference to an element from an * event definition. * * @param {djs.model.Base} element * @param {ModdleElement} definition * @param {BpmnFactory} bpmnFactory * @param {Object} options * @param {string} options.label the label of the entry * @param {string} options.description the description of the entry * @param {string} options.elementName the name of the element * @param {string} options.elementType the type of the element * @param {string} options.referenceProperty the name of referencing property * @param {string} options.newElementIdPrefix the prefix of a new created element * * @return {Array} return an array containing the entries */ module.exports = function (element, definition, bpmnFactory, options) { var elementName = options.elementName || '', elementType = options.elementType, referenceProperty = options.referenceProperty; var newElementIdPrefix = options.newElementIdPrefix || 'elem_'; var label = options.label || '', description = options.description || ''; var entries = []; entries.push({ id: 'event-definitions-' + elementName, description: description, html: '
' + '' + '
' + '' + '' + '
' + '
', get: function get(element, entryNode) { utils.updateOptionsDropDown(selector, definition, elementType, entryNode); var reference = definition.get(referenceProperty); return { selectedElement: reference && reference.id || '' }; }, set: function set(element, values) { var selection = values.selectedElement; var props = {}; if (!selection || typeof selection === 'undefined') { // remove reference to element props[referenceProperty] = undefined; return cmdHelper.updateBusinessObject(element, definition, props); } var commands = []; var selectedElement = findElementById(definition, elementType, selection); if (!selectedElement) { var root = utils.getRoot(definition); // create a new element selectedElement = elementHelper.createElement(elementType, { name: selection }, root, bpmnFactory); commands.push(cmdHelper.addAndRemoveElementsFromList(element, root, 'rootElements', null, [selectedElement])); } // update reference to element props[referenceProperty] = selectedElement; commands.push(cmdHelper.updateBusinessObject(element, definition, props)); return commands; }, addElement: function addElement(element, inputNode) { // note: this generated id will be used as name // of the element and not as id var id = utils.nextId(newElementIdPrefix); var optionTemplate = domify(''); // add new option var selectBox = getSelectBox(inputNode); selectBox.insertBefore(optionTemplate, selectBox.firstChild); // select new element in the select box forEach(selectBox, function (option) { if (option.value === id) { domAttr(option, 'selected', 'selected'); } else { domAttr(option, 'selected', null); } }); return true; } }); return entries; }; },{"../../../../Utils":5,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"lodash/collection/find":421,"lodash/collection/forEach":422,"min-dom/lib/attr":105,"min-dom/lib/domify":110,"min-dom/lib/query":112}],46:[function(require,module,exports){ 'use strict'; var eventDefinitionReference = require('./EventDefinitionReference'), elementReferenceProperty = require('./ElementReferenceProperty'); module.exports = function (group, element, bpmnFactory, messageEventDefinition) { group.entries = group.entries.concat(eventDefinitionReference(element, messageEventDefinition, bpmnFactory, { label: 'Message', elementName: 'message', elementType: 'bpmn:Message', referenceProperty: 'messageRef', newElementIdPrefix: 'Message_' })); group.entries = group.entries.concat(elementReferenceProperty(element, messageEventDefinition, bpmnFactory, { id: 'message-element-name', label: 'Message Name', referenceProperty: 'messageRef', modelProperty: 'name', shouldValidate: true })); }; },{"./ElementReferenceProperty":42,"./EventDefinitionReference":45}],47:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'); /** * Create an entry to modify the name of an an element. * * @param {djs.model.Base} element * @param {Object} options * @param {string} options.id the id of the entry * @param {string} options.label the label of the entry * * @return {Array} return an array containing * the entry to modify the name */ module.exports = function (element, options, translate) { options = options || {}; var id = options.id || 'name', label = options.label || translate('Name'), modelProperty = options.modelProperty || 'name'; var nameEntry = entryFactory.textBox({ id: id, label: label, modelProperty: modelProperty }); return [nameEntry]; }; },{"../../../../factory/EntryFactory":14}],48:[function(require,module,exports){ 'use strict'; var eventDefinitionReference = require('./EventDefinitionReference'), elementReferenceProperty = require('./ElementReferenceProperty'); module.exports = function (group, element, bpmnFactory, signalEventDefinition) { group.entries = group.entries.concat(eventDefinitionReference(element, signalEventDefinition, bpmnFactory, { label: 'Signal', elementName: 'signal', elementType: 'bpmn:Signal', referenceProperty: 'signalRef', newElementIdPrefix: 'Signal_' })); group.entries = group.entries.concat(elementReferenceProperty(element, signalEventDefinition, bpmnFactory, { id: 'signal-element-name', label: 'Signal Name', referenceProperty: 'signalRef', modelProperty: 'name', shouldValidate: true })); }; },{"./ElementReferenceProperty":42,"./EventDefinitionReference":45}],49:[function(require,module,exports){ 'use strict'; var elementHelper = require('../../../../helper/ElementHelper'), cmdHelper = require('../../../../helper/CmdHelper'); var entryFactory = require('../../../../factory/EntryFactory'); /** * Get the timer definition type for a given timer event definition. * * @param {ModdleElement} timer * * @return {string|undefined} the timer definition type */ function getTimerDefinitionType(timer) { var timeDate = timer.get('timeDate'); if (typeof timeDate !== 'undefined') { return 'timeDate'; } var timeCycle = timer.get('timeCycle'); if (typeof timeCycle !== 'undefined') { return 'timeCycle'; } var timeDuration = timer.get('timeDuration'); if (typeof timeDuration !== 'undefined') { return 'timeDuration'; } } /** * Creates 'bpmn:FormalExpression' element. * * @param {ModdleElement} parent * @param {string} body * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} a formal expression */ function createFormalExpression(parent, body, bpmnFactory) { body = body || undefined; return elementHelper.createElement('bpmn:FormalExpression', { body: body }, parent, bpmnFactory); } function TimerEventDefinition(group, element, bpmnFactory, timerEventDefinition) { var selectOptions = [{ value: 'timeDate', name: 'Date' }, { value: 'timeDuration', name: 'Duration' }, { value: 'timeCycle', name: 'Cycle' }]; group.entries.push(entryFactory.selectBox({ id: 'timer-event-definition-type', label: 'Timer Definition Type', selectOptions: selectOptions, emptyParameter: true, modelProperty: 'timerDefinitionType', get: function get(element, node) { return { timerDefinitionType: getTimerDefinitionType(timerEventDefinition) || '' }; }, set: function set(element, values) { var props = { timeDuration: undefined, timeDate: undefined, timeCycle: undefined }; var newType = values.timerDefinitionType; if (values.timerDefinitionType) { var oldType = getTimerDefinitionType(timerEventDefinition); var value; if (oldType) { var definition = timerEventDefinition.get(oldType); value = definition.get('body'); } props[newType] = createFormalExpression(timerEventDefinition, value, bpmnFactory); } return cmdHelper.updateBusinessObject(element, timerEventDefinition, props); } })); group.entries.push(entryFactory.textField({ id: 'timer-event-definition', label: 'Timer Definition', modelProperty: 'timerDefinition', get: function get(element, node) { var type = getTimerDefinitionType(timerEventDefinition); var definition = type && timerEventDefinition.get(type); var value = definition && definition.get('body'); return { timerDefinition: value }; }, set: function set(element, values) { var type = getTimerDefinitionType(timerEventDefinition); var definition = type && timerEventDefinition.get(type); if (definition) { return cmdHelper.updateBusinessObject(element, definition, { body: values.timerDefinition || undefined }); } }, validate: function validate(element) { var type = getTimerDefinitionType(timerEventDefinition); var definition = type && timerEventDefinition.get(type); if (definition) { var value = definition.get('body'); if (!value) { return { timerDefinition: 'Must provide a value' }; } } }, hidden: function hidden(element) { return !getTimerDefinitionType(timerEventDefinition); } })); } module.exports = TimerEventDefinition; },{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25}],50:[function(require,module,exports){ 'use strict'; var inherits = require('inherits'); var PropertiesActivator = require('../../PropertiesActivator'); var asyncCapableHelper = require('../../helper/AsyncCapableHelper'), ImplementationTypeHelper = require('../../helper/ImplementationTypeHelper'); var is = require('bpmn-js/lib/util/ModelUtil').is; // bpmn properties var processProps = require('../bpmn/parts/ProcessProps'), eventProps = require('../bpmn/parts/EventProps'), linkProps = require('../bpmn/parts/LinkProps'), documentationProps = require('../bpmn/parts/DocumentationProps'), idProps = require('../bpmn/parts/IdProps'), nameProps = require('../bpmn/parts/NameProps'), executableProps = require('../bpmn/parts/ExecutableProps'); // camunda properties var serviceTaskDelegateProps = require('./parts/ServiceTaskDelegateProps'), userTaskProps = require('./parts/UserTaskProps'), asynchronousContinuationProps = require('./parts/AsynchronousContinuationProps'), callActivityProps = require('./parts/CallActivityProps'), multiInstanceProps = require('./parts/MultiInstanceLoopProps'), sequenceFlowProps = require('./parts/SequenceFlowProps'), scriptProps = require('./parts/ScriptTaskProps'), formProps = require('./parts/FormProps'), startEventInitiator = require('./parts/StartEventInitiator'), variableMapping = require('./parts/VariableMappingProps'), versionTag = require('./parts/VersionTagProps'); var listenerProps = require('./parts/ListenerProps'), listenerDetails = require('./parts/ListenerDetailProps'), listenerFields = require('./parts/ListenerFieldInjectionProps'); var elementTemplateChooserProps = require('./element-templates/parts/ChooserProps'), elementTemplateCustomProps = require('./element-templates/parts/CustomProps'); // Input/Output var inputOutput = require('./parts/InputOutputProps'), inputOutputParameter = require('./parts/InputOutputParameterProps'); // Connector var connectorDetails = require('./parts/ConnectorDetailProps'), connectorInputOutput = require('./parts/ConnectorInputOutputProps'), connectorInputOutputParameter = require('./parts/ConnectorInputOutputParameterProps'); // properties var properties = require('./parts/PropertiesProps'); // job configuration var jobConfiguration = require('./parts/JobConfigurationProps'); // history time to live var historyTimeToLive = require('./parts/HistoryTimeToLiveProps'); // external task configuration var externalTaskConfiguration = require('./parts/ExternalTaskConfigurationProps'); // field injection var fieldInjections = require('./parts/FieldInjectionProps'); var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, eventDefinitionHelper = require('../../helper/EventDefinitionHelper'), implementationTypeHelper = require('../../helper/ImplementationTypeHelper'); // helpers //////////////////////////////////////// var isExternalTaskPriorityEnabled = function isExternalTaskPriorityEnabled(element) { var businessObject = getBusinessObject(element); // show only if element is a process, a participant ... if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) { return true; } var externalBo = ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element), isExternalTask = ImplementationTypeHelper.getImplementationType(externalBo) === 'external'; // ... or an external task with selected external implementation type return !!ImplementationTypeHelper.isExternalCapable(externalBo) && isExternalTask; }; var isJobConfigEnabled = function isJobConfigEnabled(element) { var businessObject = getBusinessObject(element); if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) { return true; } // async behavior var bo = getBusinessObject(element); if (asyncCapableHelper.isAsyncBefore(bo) || asyncCapableHelper.isAsyncAfter(bo)) { return true; } // timer definition if (is(element, 'bpmn:Event')) { return !!eventDefinitionHelper.getTimerEventDefinition(element); } return false; }; var getInputOutputParameterLabel = function getInputOutputParameterLabel(param, translate) { if (is(param, 'camunda:InputParameter')) { return translate('Input Parameter'); } if (is(param, 'camunda:OutputParameter')) { return translate('Output Parameter'); } return ''; }; var getListenerLabel = function getListenerLabel(param, translate) { if (is(param, 'camunda:ExecutionListener')) { return translate('Execution Listener'); } if (is(param, 'camunda:TaskListener')) { return translate('Task Listener'); } return ''; }; function createGeneralTabGroups(element, bpmnFactory, elementRegistry, elementTemplates, translate) { var generalGroup = { id: 'general', label: translate('General'), entries: [] }; idProps(generalGroup, element, translate); nameProps(generalGroup, element, translate); processProps(generalGroup, element, translate); versionTag(generalGroup, element, translate); executableProps(generalGroup, element, translate); elementTemplateChooserProps(generalGroup, element, elementTemplates, translate); var customFieldsGroups = elementTemplateCustomProps(element, elementTemplates, bpmnFactory, translate); var detailsGroup = { id: 'details', label: translate('Details'), entries: [] }; serviceTaskDelegateProps(detailsGroup, element, bpmnFactory, translate); userTaskProps(detailsGroup, element, translate); scriptProps(detailsGroup, element, bpmnFactory, translate); linkProps(detailsGroup, element, translate); callActivityProps(detailsGroup, element, bpmnFactory, translate); eventProps(detailsGroup, element, bpmnFactory, elementRegistry, translate); sequenceFlowProps(detailsGroup, element, bpmnFactory, translate); startEventInitiator(detailsGroup, element, translate); // this must be the last element of the details group! var multiInstanceGroup = { id: 'multiInstance', label: translate('Multi Instance'), entries: [] }; multiInstanceProps(multiInstanceGroup, element, bpmnFactory, translate); var asyncGroup = { id: 'async', label: translate('Asynchronous Continuations'), entries: [] }; asynchronousContinuationProps(asyncGroup, element, bpmnFactory, translate); var jobConfigurationGroup = { id: 'jobConfiguration', label: translate('Job Configuration'), entries: [], enabled: isJobConfigEnabled }; jobConfiguration(jobConfigurationGroup, element, bpmnFactory, translate); var externalTaskGroup = { id: 'externalTaskConfiguration', label: translate('External Task Configuration'), entries: [], enabled: isExternalTaskPriorityEnabled }; externalTaskConfiguration(externalTaskGroup, element, bpmnFactory, translate); var documentationGroup = { id: 'documentation', label: translate('Documentation'), entries: [] }; documentationProps(documentationGroup, element, bpmnFactory, translate); var historyTimeToLiveGroup = { id: 'historyConfiguration', label: translate('History Configuration'), entries: [] }; historyTimeToLive(historyTimeToLiveGroup, element, bpmnFactory, translate); var groups = []; groups.push(generalGroup); customFieldsGroups.forEach(function (group) { groups.push(group); }); groups.push(detailsGroup); groups.push(externalTaskGroup); groups.push(multiInstanceGroup); groups.push(asyncGroup); groups.push(jobConfigurationGroup); groups.push(documentationGroup); groups.push(historyTimeToLiveGroup); return groups; } function createVariablesTabGroups(element, bpmnFactory, elementRegistry, translate) { var variablesGroup = { id: 'variables', label: translate('Variables'), entries: [] }; variableMapping(variablesGroup, element, bpmnFactory, translate); return [variablesGroup]; } function createFormsTabGroups(element, bpmnFactory, elementRegistry, translate) { var formGroup = { id: 'forms', label: translate('Forms'), entries: [] }; formProps(formGroup, element, bpmnFactory, translate); return [formGroup]; } function createListenersTabGroups(element, bpmnFactory, elementRegistry, translate) { var listenersGroup = { id: 'listeners', label: translate('Listeners'), entries: [] }; var options = listenerProps(listenersGroup, element, bpmnFactory, translate); var listenerDetailsGroup = { id: 'listener-details', entries: [], enabled: function enabled(element, node) { return options.getSelectedListener(element, node); }, label: function label(element, node) { var param = options.getSelectedListener(element, node); return getListenerLabel(param, translate); } }; listenerDetails(listenerDetailsGroup, element, bpmnFactory, options, translate); var listenerFieldsGroup = { id: 'listener-fields', label: translate('Field Injection'), entries: [], enabled: function enabled(element, node) { return options.getSelectedListener(element, node); } }; listenerFields(listenerFieldsGroup, element, bpmnFactory, options, translate); return [listenersGroup, listenerDetailsGroup, listenerFieldsGroup]; } function createInputOutputTabGroups(element, bpmnFactory, elementRegistry, translate) { var inputOutputGroup = { id: 'input-output', label: translate('Parameters'), entries: [] }; var options = inputOutput(inputOutputGroup, element, bpmnFactory, translate); var inputOutputParameterGroup = { id: 'input-output-parameter', entries: [], enabled: function enabled(element, node) { return options.getSelectedParameter(element, node); }, label: function label(element, node) { var param = options.getSelectedParameter(element, node); return getInputOutputParameterLabel(param, translate); } }; inputOutputParameter(inputOutputParameterGroup, element, bpmnFactory, options, translate); return [inputOutputGroup, inputOutputParameterGroup]; } function createConnectorTabGroups(element, bpmnFactory, elementRegistry, translate) { var connectorDetailsGroup = { id: 'connector-details', label: translate('Details'), entries: [] }; connectorDetails(connectorDetailsGroup, element, bpmnFactory, translate); var connectorInputOutputGroup = { id: 'connector-input-output', label: translate('Input/Output'), entries: [] }; var options = connectorInputOutput(connectorInputOutputGroup, element, bpmnFactory, translate); var connectorInputOutputParameterGroup = { id: 'connector-input-output-parameter', entries: [], enabled: function enabled(element, node) { return options.getSelectedParameter(element, node); }, label: function label(element, node) { var param = options.getSelectedParameter(element, node); return getInputOutputParameterLabel(param, translate); } }; connectorInputOutputParameter(connectorInputOutputParameterGroup, element, bpmnFactory, options, translate); return [connectorDetailsGroup, connectorInputOutputGroup, connectorInputOutputParameterGroup]; } function createFieldInjectionsTabGroups(element, bpmnFactory, elementRegistry, translate) { var fieldGroup = { id: 'field-injections-properties', label: translate('Field Injections'), entries: [] }; fieldInjections(fieldGroup, element, bpmnFactory, translate); return [fieldGroup]; } function createExtensionElementsGroups(element, bpmnFactory, elementRegistry, translate) { var propertiesGroup = { id: 'extensionElements-properties', label: translate('Properties'), entries: [] }; properties(propertiesGroup, element, bpmnFactory, translate); return [propertiesGroup]; } // Camunda Properties Provider ///////////////////////////////////// /** * A properties provider for Camunda related properties. * * @param {EventBus} eventBus * @param {BpmnFactory} bpmnFactory * @param {ElementRegistry} elementRegistry * @param {ElementTemplates} elementTemplates */ function CamundaPropertiesProvider(eventBus, bpmnFactory, elementRegistry, elementTemplates, translate) { PropertiesActivator.call(this, eventBus); this.getTabs = function (element) { var generalTab = { id: 'general', label: translate('General'), groups: createGeneralTabGroups(element, bpmnFactory, elementRegistry, elementTemplates, translate) }; var variablesTab = { id: 'variables', label: translate('Variables'), groups: createVariablesTabGroups(element, bpmnFactory, elementRegistry, translate) }; var formsTab = { id: 'forms', label: translate('Forms'), groups: createFormsTabGroups(element, bpmnFactory, elementRegistry, translate) }; var listenersTab = { id: 'listeners', label: translate('Listeners'), groups: createListenersTabGroups(element, bpmnFactory, elementRegistry, translate), enabled: function enabled(element) { return !eventDefinitionHelper.getLinkEventDefinition(element) || !is(element, 'bpmn:IntermediateThrowEvent') && eventDefinitionHelper.getLinkEventDefinition(element); } }; var inputOutputTab = { id: 'input-output', label: translate('Input/Output'), groups: createInputOutputTabGroups(element, bpmnFactory, elementRegistry, translate) }; var connectorTab = { id: 'connector', label: translate('Connector'), groups: createConnectorTabGroups(element, bpmnFactory, elementRegistry, translate), enabled: function enabled(element) { var bo = implementationTypeHelper.getServiceTaskLikeBusinessObject(element); return bo && implementationTypeHelper.getImplementationType(bo) === 'connector'; } }; var fieldInjectionsTab = { id: 'field-injections', label: translate('Field Injections'), groups: createFieldInjectionsTabGroups(element, bpmnFactory, elementRegistry, translate) }; var extensionsTab = { id: 'extensionElements', label: translate('Extensions'), groups: createExtensionElementsGroups(element, bpmnFactory, elementRegistry, translate) }; return [generalTab, variablesTab, connectorTab, formsTab, listenersTab, inputOutputTab, fieldInjectionsTab, extensionsTab]; }; } CamundaPropertiesProvider.$inject = ['eventBus', 'bpmnFactory', 'elementRegistry', 'elementTemplates', 'translate']; inherits(CamundaPropertiesProvider, PropertiesActivator); module.exports = CamundaPropertiesProvider; },{"../../PropertiesActivator":3,"../../helper/AsyncCapableHelper":23,"../../helper/EventDefinitionHelper":26,"../../helper/ImplementationTypeHelper":29,"../bpmn/parts/DocumentationProps":33,"../bpmn/parts/EventProps":34,"../bpmn/parts/ExecutableProps":35,"../bpmn/parts/IdProps":36,"../bpmn/parts/LinkProps":37,"../bpmn/parts/NameProps":38,"../bpmn/parts/ProcessProps":39,"./element-templates/parts/ChooserProps":60,"./element-templates/parts/CustomProps":61,"./parts/AsynchronousContinuationProps":63,"./parts/CallActivityProps":64,"./parts/ConnectorDetailProps":65,"./parts/ConnectorInputOutputParameterProps":66,"./parts/ConnectorInputOutputProps":67,"./parts/ExternalTaskConfigurationProps":68,"./parts/FieldInjectionProps":69,"./parts/FormProps":70,"./parts/HistoryTimeToLiveProps":71,"./parts/InputOutputParameterProps":72,"./parts/InputOutputProps":73,"./parts/JobConfigurationProps":74,"./parts/ListenerDetailProps":75,"./parts/ListenerFieldInjectionProps":76,"./parts/ListenerProps":77,"./parts/MultiInstanceLoopProps":78,"./parts/PropertiesProps":79,"./parts/ScriptTaskProps":80,"./parts/SequenceFlowProps":81,"./parts/ServiceTaskDelegateProps":82,"./parts/StartEventInitiator":83,"./parts/UserTaskProps":84,"./parts/VariableMappingProps":85,"./parts/VersionTagProps":86,"bpmn-js/lib/util/ModelUtil":216,"inherits":415}],51:[function(require,module,exports){ 'use strict'; var assign = require('lodash/object/assign'); /** * Create an input parameter representing the given * binding and value. * * @param {PropertyBinding} binding * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} */ function createInputParameter(binding, value, bpmnFactory) { var scriptFormat = binding.scriptFormat, parameterValue, parameterDefinition; if (scriptFormat) { parameterDefinition = bpmnFactory.create('camunda:Script', { scriptFormat: scriptFormat, value: value }); } else { parameterValue = value; } return bpmnFactory.create('camunda:InputParameter', { name: binding.name, value: parameterValue, definition: parameterDefinition }); } module.exports.createInputParameter = createInputParameter; /** * Create an output parameter representing the given * binding and value. * * @param {PropertyBinding} binding * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} */ function createOutputParameter(binding, value, bpmnFactory) { var scriptFormat = binding.scriptFormat, parameterValue, parameterDefinition; if (scriptFormat) { parameterDefinition = bpmnFactory.create('camunda:Script', { scriptFormat: scriptFormat, value: binding.source }); } else { parameterValue = binding.source; } return bpmnFactory.create('camunda:OutputParameter', { name: value, value: parameterValue, definition: parameterDefinition }); } module.exports.createOutputParameter = createOutputParameter; /** * Create camunda property from the given binding. * * @param {PropertyBinding} binding * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} */ function createCamundaProperty(binding, value, bpmnFactory) { return bpmnFactory.create('camunda:Property', { name: binding.name, value: value || '' }); } module.exports.createCamundaProperty = createCamundaProperty; /** * Create camunda:in element from given binding. * * @param {PropertyBinding} binding * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} */ function createCamundaIn(binding, value, bpmnFactory) { var properties = createCamundaInOutAttrs(binding, value); return bpmnFactory.create('camunda:In', properties); } module.exports.createCamundaIn = createCamundaIn; /** * Create camunda:in with businessKey element from given binding. * * @param {PropertyBinding} binding * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} */ function createCamundaInWithBusinessKey(binding, value, bpmnFactory) { return bpmnFactory.create('camunda:In', { businessKey: value }); } module.exports.createCamundaInWithBusinessKey = createCamundaInWithBusinessKey; /** * Create camunda:out element from given binding. * * @param {PropertyBinding} binding * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} */ function createCamundaOut(binding, value, bpmnFactory) { var properties = createCamundaInOutAttrs(binding, value); return bpmnFactory.create('camunda:Out', properties); } module.exports.createCamundaOut = createCamundaOut; /** * Create camunda:executionListener element containing an inline script from given binding. * * @param {PropertyBinding} binding * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} */ function createCamundaExecutionListenerScript(binding, value, bpmnFactory) { var scriptFormat = binding.scriptFormat, parameterValue, parameterDefinition; if (scriptFormat) { parameterDefinition = bpmnFactory.create('camunda:Script', { scriptFormat: scriptFormat, value: value }); } else { parameterValue = value; } return bpmnFactory.create('camunda:ExecutionListener', { event: binding.event, value: parameterValue, script: parameterDefinition }); } module.exports.createCamundaExecutionListenerScript = createCamundaExecutionListenerScript; /** * Create camunda:field element containing string or expression from given binding. * * @param {PropertyBinding} binding * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} */ function createCamundaFieldInjection(binding, value, bpmnFactory) { var DEFAULT_PROPS = { 'string': undefined, 'expression': undefined, 'name': undefined }; var props = assign({}, DEFAULT_PROPS); if (!binding.expression) { props.string = value; } else { props.expression = value; } props.name = binding.name; return bpmnFactory.create('camunda:Field', props); } module.exports.createCamundaFieldInjection = createCamundaFieldInjection; /////////// helpers //////////////////////////// /** * Create properties for camunda:in and camunda:out types. */ function createCamundaInOutAttrs(binding, value) { var properties = {}; // camunda:in source(Expression) target if (binding.target) { properties.target = binding.target; if (binding.expression) { properties.sourceExpression = value; } else { properties.source = value; } } else // camunda:(in|out) variables local if (binding.variables) { properties.variables = 'all'; if (binding.variables === 'local') { properties.local = true; } } // camunda:out source(Expression) target else { properties.target = value; ['source', 'sourceExpression'].forEach(function (k) { if (binding[k]) { properties[k] = binding[k]; } }); } return properties; } },{"lodash/object/assign":496}],52:[function(require,module,exports){ 'use strict'; var inherits = require('inherits'); var getTemplate = require('./Helper').getTemplate; var PropertiesActivator = require('../../../PropertiesActivator'); var HIGHER_PRIORITY = 1100; /** * Applies template visibility settings. * * Controlled using `entriesVisible` on template config object: * * ```json * "entriesVisible": { * "_all": true|false, * "entryName": true|false, * ... * } * ``` * * @param {EventBus} eventBus * @param {ElementTemplates} elementTemplates */ function CustomElementsPropertiesActivator(eventBus, elementTemplates) { PropertiesActivator.call(this, eventBus, HIGHER_PRIORITY); this.isEntryVisible = function (entry, element) { var template = getTemplate(element, elementTemplates); if (template && !isEntryVisible(entry, template)) { return false; } }; this.isPropertyEditable = function (entry, propertyName, element) { var template = getTemplate(element, elementTemplates); if (template && !isEntryEditable(entry, template)) { return false; } }; } CustomElementsPropertiesActivator.$inject = ['eventBus', 'elementTemplates']; inherits(CustomElementsPropertiesActivator, PropertiesActivator); module.exports = CustomElementsPropertiesActivator; ////// helpers //////////////////////////////////// var CUSTOM_PROPERTIES_PATTERN = /^custom-/; var DEFAULT_ENTRIES_VISIBLE = { _all: false, id: true, name: true }; function isCustomEntry(entry) { return CUSTOM_PROPERTIES_PATTERN.test(entry.id); } function isEntryVisible(entry, template) { var entryId = entry.id; if (entryId === 'elementTemplate-chooser' || isCustomEntry(entry)) { return true; } var entriesVisible = template.entriesVisible || DEFAULT_ENTRIES_VISIBLE; if (typeof entriesVisible === 'boolean') { return entriesVisible; } var defaultVisible = entriesVisible._all || false, entryVisible = entriesVisible[entryId]; // d = true, e = false => false // d = false, e = true => true // d = false, e = false return defaultVisible === true && entryVisible !== false || defaultVisible === false && entryVisible === true; } function isEntryEditable(entry, template) { var property; if (isCustomEntry(entry)) { property = getProperty(template, entry); return property && property.editable !== false; } return true; } function getProperty(template, entry) { var index; var idx = entry.id.replace('custom-' + template.id + '-', ''); if (idx.indexOf('-') !== -1) { var indexes = idx.split('-'); if (indexes.length == 2) { var scopeName = indexes[0].replace(/_/g, ':'); index = parseInt(indexes[1], 10); if (scopeName && !isNaN(index)) { return template.scopes[scopeName].properties[index]; } } } else { index = parseInt(idx, 10); if (!isNaN(index)) { return template.properties[index]; } } throw new Error('cannot extract property index for entry <' + entry.id + '>'); } },{"../../../PropertiesActivator":3,"./Helper":55,"inherits":415}],53:[function(require,module,exports){ 'use strict'; var values = require('lodash/object/values'); /** * The guy knowing all configured element templates. * * This registry won't validate. Use the {@link Validator} * to verify a template is valid prior to adding it to * this registry. */ function ElementTemplates() { this._templates = {}; /** * Sets the known element templates. * * @param {Array} descriptors * * @return {ElementTemplates} */ this.set = function (descriptors) { var templates = this._templates = {}; descriptors.forEach(function (descriptor) { templates[descriptor.id] = descriptor; }); return this; }; /** * Get template descriptor with given id. * * @param {String} id * * @return {TemplateDescriptor} */ this.get = function (id) { return this._templates[id]; }; /** * Return all known template descriptors. * * @return {Array} */ this.getAll = function () { return values(this._templates); }; } module.exports = ElementTemplates; },{"lodash/object/values":502}],54:[function(require,module,exports){ 'use strict'; var Validator = require('./Validator'); /** * The guy responsible for template loading. * * Provide the actual templates via the `config.elementTemplates`. * * That configuration can either be an array of template * descriptors or a node style callback to retrieve * the templates asynchronously. * * @param {Array|Function} loadTemplates * @param {EventBus} eventBus * @param {ElementTemplates} elementTemplates */ function ElementTemplatesLoader(loadTemplates, eventBus, elementTemplates) { this._loadTemplates = loadTemplates; this._eventBus = eventBus; this._elementTemplates = elementTemplates; var self = this; eventBus.on('diagram.init', function () { self.reload(); }); } module.exports = ElementTemplatesLoader; ElementTemplatesLoader.$inject = ['config.elementTemplates', 'eventBus', 'elementTemplates']; ElementTemplatesLoader.prototype.reload = function () { var self = this; var loadTemplates = this._loadTemplates; // no templates specified if (typeof loadTemplates === 'undefined') { return; } // template loader function specified if (typeof loadTemplates === 'function') { return loadTemplates(function (err, templates) { if (err) { return self.templateErrors([err]); } self.setTemplates(templates); }); } // templates array specified if (loadTemplates.length) { return this.setTemplates(loadTemplates); } }; ElementTemplatesLoader.prototype.setTemplates = function (templates) { var elementTemplates = this._elementTemplates; var validator = new Validator().addAll(templates); var errors = validator.getErrors(), validTemplates = validator.getValidTemplates(); elementTemplates.set(validTemplates); if (errors.length) { this.templateErrors(errors); } this.templatesChanged(); }; ElementTemplatesLoader.prototype.templatesChanged = function () { this._eventBus.fire('elementTemplates.changed'); }; ElementTemplatesLoader.prototype.templateErrors = function (errors) { this._eventBus.fire('elementTemplates.errors', { errors: errors }); }; },{"./Validator":56}],55:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var is = require('bpmn-js/lib/util/ModelUtil').is, isAny = require('bpmn-js/lib/features/modeling/util/ModelingUtil').isAny; var find = require('lodash/collection/find'); var TEMPLATE_ATTR = 'camunda:modelerTemplate'; /** * The BPMN 2.0 extension attribute name under * which the element template is stored. * * @type {String} */ module.exports.TEMPLATE_ATTR = TEMPLATE_ATTR; /** * Get template id for a given diagram element. * * @param {djs.model.Base} element * * @return {String} */ function getTemplateId(element) { var bo = getBusinessObject(element); if (bo) { return bo.get(TEMPLATE_ATTR); } } module.exports.getTemplateId = getTemplateId; /** * Get template of a given element. * * @param {Element} element * @param {ElementTemplates} elementTemplates * * @return {TemplateDefinition} */ function getTemplate(element, elementTemplates) { var id = getTemplateId(element); return id && elementTemplates.get(id); } module.exports.getTemplate = getTemplate; /** * Get default template for a given element. * * @param {Element} element * @param {ElementTemplates} elementTemplates * * @return {TemplateDefinition} */ function getDefaultTemplate(element, elementTemplates) { // return first default template, if any exists return elementTemplates.getAll().filter(function (t) { return isAny(element, t.appliesTo) && t.isDefault; })[0]; } module.exports.getDefaultTemplate = getDefaultTemplate; /** * Find extension with given type in * BPMN element, diagram element or ExtensionElement. * * @param {ModdleElement|djs.model.Base} element * @param {String} type * * @return {ModdleElement} the extension */ function findExtension(element, type) { var bo = getBusinessObject(element); var extensionElements; if (is(bo, 'bpmn:ExtensionElements')) { extensionElements = bo; } else { extensionElements = bo.extensionElements; } if (!extensionElements) { return null; } return find(extensionElements.get('values'), function (e) { return is(e, type); }); } module.exports.findExtension = findExtension; function findExtensions(element, types) { var extensionElements = getExtensionElements(element); if (!extensionElements) { return []; } return extensionElements.get('values').filter(function (e) { return isAny(e, types); }); } module.exports.findExtensions = findExtensions; function findCamundaInOut(element, binding) { var extensionElements = getExtensionElements(element); if (!extensionElements) { return; } var matcher; if (binding.type === 'camunda:in') { matcher = function matcher(e) { return is(e, 'camunda:In') && isInOut(e, binding); }; } else if (binding.type === 'camunda:out') { matcher = function matcher(e) { return is(e, 'camunda:Out') && isInOut(e, binding); }; } else if (binding.type === 'camunda:in:businessKey') { matcher = function matcher(e) { return is(e, 'camunda:In') && 'businessKey' in e; }; } return find(extensionElements.get('values'), matcher); } module.exports.findCamundaInOut = findCamundaInOut; function findCamundaProperty(camundaProperties, binding) { return find(camundaProperties.get('values'), function (p) { return p.name === binding.name; }); } module.exports.findCamundaProperty = findCamundaProperty; function findInputParameter(inputOutput, binding) { var parameters = inputOutput.get('inputParameters'); return find(parameters, function (p) { return p.name === binding.name; }); } module.exports.findInputParameter = findInputParameter; function findOutputParameter(inputOutput, binding) { var parameters = inputOutput.get('outputParameters'); return find(parameters, function (p) { var value = p.value; if (!binding.scriptFormat) { return value === binding.source; } var definition = p.definition; if (!definition || binding.scriptFormat !== definition.scriptFormat) { return false; } return definition.value === binding.source; }); } module.exports.findOutputParameter = findOutputParameter; //////// helpers ///////////////////////////////// function getExtensionElements(element) { var bo = getBusinessObject(element); if (is(bo, 'bpmn:ExtensionElements')) { return bo; } else { return bo.extensionElements; } } function isInOut(element, binding) { if (binding.type === 'camunda:in') { // find based on target attribute if (binding.target) { return element.target === binding.target; } } if (binding.type === 'camunda:out') { // find based on source / sourceExpression if (binding.source) { return element.source === binding.source; } if (binding.sourceExpression) { return element.sourceExpression === binding.sourceExpression; } } // find based variables / local combination if (binding.variables) { return element.variables === 'all' && (binding.variables !== 'local' || element.local); } } },{"bpmn-js/lib/features/modeling/util/ModelingUtil":189,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/find":421}],56:[function(require,module,exports){ 'use strict'; var isArray = require('lodash/lang/isArray'); var isObject = require('lodash/lang/isObject'); var DROPDOWN_TYPE = 'Dropdown'; var VALID_TYPES = ['String', 'Text', 'Boolean', 'Hidden', DROPDOWN_TYPE]; var PROPERTY_TYPE = 'property', CAMUNDA_PROPERTY_TYPE = 'camunda:property', CAMUNDA_INPUT_PARAMETER_TYPE = 'camunda:inputParameter', CAMUNDA_OUTPUT_PARAMETER_TYPE = 'camunda:outputParameter', CAMUNDA_IN_TYPE = 'camunda:in', CAMUNDA_OUT_TYPE = 'camunda:out', CAMUNDA_IN_BUSINESS_KEY_TYPE = 'camunda:in:businessKey', CAMUNDA_EXECUTION_LISTENER = 'camunda:executionListener', CAMUNDA_FIELD = 'camunda:field'; var VALID_BINDING_TYPES = [PROPERTY_TYPE, CAMUNDA_PROPERTY_TYPE, CAMUNDA_INPUT_PARAMETER_TYPE, CAMUNDA_OUTPUT_PARAMETER_TYPE, CAMUNDA_IN_TYPE, CAMUNDA_OUT_TYPE, CAMUNDA_IN_BUSINESS_KEY_TYPE, CAMUNDA_EXECUTION_LISTENER, CAMUNDA_FIELD]; /** * A element template validator. */ function Validator() { this._templatesById = {}; this._validTemplates = []; this._errors = []; /** * Adds the templates. * * @param {Array} templates * * @return {Validator} self */ this.addAll = function (templates) { if (!isArray(templates)) { this._logError('templates must be []'); } else { templates.forEach(this.add, this); } return this; }; /** * Add the given element template, if it is valid. * * @param {TemplateDescriptor} template * * @return {Validator} self */ this.add = function (template) { var err = this._validateTemplate(template); if (!err) { this._templatesById[template.id] = template; this._validTemplates.push(template); } return this; }; /** * Validate given template and return error (if any). * * @param {TemplateDescriptor} template * * @return {Error} validation error, if any */ this._validateTemplate = function (template) { var err, id = template.id, appliesTo = template.appliesTo, properties = template.properties, scopes = template.scopes; if (!id) { return this._logError('missing template id'); } if (id in this._templatesById) { return this._logError('template id <' + id + '> already used'); } if (!isArray(appliesTo)) { err = this._logError('missing appliesTo=[]', template); } if (!isArray(properties)) { err = this._logError('missing properties=[]', template); } else { if (!this._validateProperties(properties)) { err = new Error('invalid properties'); } } if (scopes) { err = this._validateScopes(template, scopes); } return err; }; this._validateScopes = function (template, scopes) { var err, scope, scopeName; if (!isObject(scopes) || isArray(scopes)) { return this._logError('invalid scopes, should be scopes={}', template); } for (scopeName in scopes) { scope = scopes[scopeName]; if (!isObject(scope) || isArray(scope)) { err = this._logError('invalid scope, should be scope={}', template); } if (!isArray(scope.properties)) { err = this._logError('missing properties=[] in scope <' + scopeName + '>', template); } else { if (!this._validateProperties(scope.properties)) { err = new Error('invalid properties in scope <' + scopeName + '>'); } } } return err; }; /** * Validate properties and return false if any is invalid. * * @param {Array} properties * * @return {Boolean} true if all properties are valid */ this._validateProperties = function (properties) { var validProperties = properties.filter(this._validateProperty, this); return properties.length === validProperties.length; }; /** * Validate property and return false, if there was * a validation error. * * @param {PropertyDescriptor} property * * @return {Boolean} true if property is valid */ this._validateProperty = function (property) { var type = property.type, binding = property.binding; var err; var bindingType = binding.type; if (VALID_TYPES.indexOf(type) === -1) { err = this._logError('invalid property type <' + type + '>; ' + 'must be any of { ' + VALID_TYPES.join(', ') + ' }'); } if (type === DROPDOWN_TYPE && bindingType !== CAMUNDA_EXECUTION_LISTENER) { if (!isArray(property.choices)) { err = this._logError('must provide choices=[] with ' + DROPDOWN_TYPE + ' type'); } else if (!property.choices.every(isDropdownChoiceValid)) { err = this._logError('{ name, value } must be specified for ' + DROPDOWN_TYPE + ' choices'); } } if (!binding) { return this._logError('property missing binding'); } if (VALID_BINDING_TYPES.indexOf(bindingType) === -1) { err = this._logError('invalid property.binding type <' + bindingType + '>; ' + 'must be any of { ' + VALID_BINDING_TYPES.join(', ') + ' }'); } if (bindingType === PROPERTY_TYPE || bindingType === CAMUNDA_PROPERTY_TYPE || bindingType === CAMUNDA_INPUT_PARAMETER_TYPE || bindingType === CAMUNDA_FIELD) { if (!binding.name) { err = this._logError('property.binding <' + bindingType + '> requires name'); } } if (bindingType === CAMUNDA_OUTPUT_PARAMETER_TYPE) { if (!binding.source) { err = this._logError('property.binding <' + bindingType + '> requires source'); } } if (bindingType === CAMUNDA_IN_TYPE) { if (!binding.variables && !binding.target) { err = this._logError('property.binding <' + bindingType + '> requires ' + 'variables or target'); } } if (bindingType === CAMUNDA_OUT_TYPE) { if (!binding.variables && !binding.source && !binding.sourceExpression) { err = this._logError('property.binding <' + bindingType + '> requires ' + 'variables, sourceExpression or source'); } } if (bindingType === CAMUNDA_EXECUTION_LISTENER) { if (type !== 'Hidden') { err = this._logError('invalid property type <' + type + '> for ' + CAMUNDA_EXECUTION_LISTENER + '; ' + 'must be '); } } return !err; }; this._logError = function (err, template) { if (typeof err === 'string') { if (template) { err = 'template(id: ' + template.id + ') ' + err; } err = new Error(err); } this._errors.push(err); return err; }; this.getErrors = function () { return this._errors; }; this.getValidTemplates = function () { return this._validTemplates; }; } module.exports = Validator; //////// helpers /////////////////////////////////// function isDropdownChoiceValid(c) { return 'name' in c && 'value' in c; } },{"lodash/lang/isArray":489,"lodash/lang/isObject":493}],57:[function(require,module,exports){ 'use strict'; var findExtension = require('../Helper').findExtension, findExtensions = require('../Helper').findExtensions; var createCamundaProperty = require('../CreateHelper').createCamundaProperty, createInputParameter = require('../CreateHelper').createInputParameter, createOutputParameter = require('../CreateHelper').createOutputParameter, createCamundaIn = require('../CreateHelper').createCamundaIn, createCamundaOut = require('../CreateHelper').createCamundaOut, createCamundaInWithBusinessKey = require('../CreateHelper').createCamundaInWithBusinessKey, createCamundaExecutionListenerScript = require('../CreateHelper').createCamundaExecutionListenerScript, createCamundaFieldInjection = require('../CreateHelper').createCamundaFieldInjection; var forEach = require('lodash/collection/forEach'); var CAMUNDA_SERVICE_TASK_LIKE = ['camunda:class', 'camunda:delegateExpression', 'camunda:expression']; /** * A handler that changes the modeling template of a BPMN element. */ function ChangeElementTemplateHandler(modeling, commandStack, bpmnFactory) { function getOrCreateExtensionElements(element) { var bo = element.businessObject; var extensionElements = bo.extensionElements; // add extension elements if (!extensionElements) { extensionElements = bpmnFactory.create('bpmn:ExtensionElements', { values: [] }); modeling.updateProperties(element, { extensionElements: extensionElements }); } return extensionElements; } function updateModelerTemplate(element, newTemplate) { modeling.updateProperties(element, { 'camunda:modelerTemplate': newTemplate && newTemplate.id }); } function updateIoMappings(element, newTemplate, context) { var newMappings = createInputOutputMappings(newTemplate, bpmnFactory), oldMappings; if (!newMappings) { return; } if (context) { commandStack.execute('properties-panel.update-businessobject', { element: element, businessObject: context, properties: { inputOutput: newMappings } }); } else { context = getOrCreateExtensionElements(element); oldMappings = findExtension(element, 'camunda:InputOutput'); commandStack.execute('properties-panel.update-businessobject-list', { element: element, currentObject: context, propertyName: 'values', objectsToAdd: [newMappings], objectsToRemove: oldMappings ? [oldMappings] : [] }); } } function updateCamundaField(element, newTemplate, context) { var newMappings = createCamundaFieldInjections(newTemplate, bpmnFactory), oldMappings; if (!newMappings) { return; } if (context) { commandStack.execute('properties-panel.update-businessobject', { element: element, businessObject: context, properties: { field: newMappings } }); } else { context = getOrCreateExtensionElements(element); oldMappings = findExtensions(element, ['camunda:Field']); commandStack.execute('properties-panel.update-businessobject-list', { element: element, currentObject: context, propertyName: 'values', objectsToAdd: newMappings, objectsToRemove: oldMappings ? oldMappings : [] }); } } function updateCamundaProperties(element, newTemplate, context) { var newProperties = createCamundaProperties(newTemplate, bpmnFactory), oldProperties; if (!newProperties) { return; } if (context) { commandStack.execute('properties-panel.update-businessobject', { element: element, businessObject: context, properties: { properties: newProperties } }); } else { context = getOrCreateExtensionElements(element); oldProperties = findExtension(element, 'camunda:Properties'); commandStack.execute('properties-panel.update-businessobject-list', { element: element, currentObject: context, propertyName: 'values', objectsToAdd: [newProperties], objectsToRemove: oldProperties ? [oldProperties] : [] }); } } function updateProperties(element, newTemplate, context) { var newProperties = createBpmnPropertyUpdates(newTemplate, bpmnFactory); var newPropertiesCount = Object.keys(newProperties).length; if (!newPropertiesCount) { return; } if (context) { commandStack.execute('properties-panel.update-businessobject', { element: element, businessObject: context, properties: newProperties }); } else { modeling.updateProperties(element, newProperties); } } function updateInOut(element, newTemplate, context) { var newInOut = createCamundaInOut(newTemplate, bpmnFactory), oldInOut; if (!newInOut) { return; } if (context) { commandStack.execute('properties-panel.update-businessobject', { element: element, businessObject: context, properties: { inout: newInOut } }); } else { context = getOrCreateExtensionElements(element); oldInOut = findExtensions(context, ['camunda:In', 'camunda:Out']); commandStack.execute('properties-panel.update-businessobject-list', { element: element, currentObject: context, propertyName: 'values', objectsToAdd: newInOut, objectsToRemove: oldInOut }); } } function updateExecutionListener(element, newTemplate, context) { var newExecutionListeners = createCamundaExecutionListeners(newTemplate, bpmnFactory), oldExecutionsListeners; if (!newExecutionListeners.length) { return; } if (context) { commandStack.execute('properties-panel.update-businessobject', { element: element, businessObject: context, properties: { executionListener: newExecutionListeners } }); } else { context = getOrCreateExtensionElements(element); oldExecutionsListeners = findExtensions(context, ['camunda:ExecutionListener']); commandStack.execute('properties-panel.update-businessobject-list', { element: element, currentObject: context, propertyName: 'values', objectsToAdd: newExecutionListeners, objectsToRemove: oldExecutionsListeners }); } } /** * Update / recreate a scoped element. * * @param {djs.model.Base} element the diagram parent element * @param {String} scopeName name of the scope, i.e. camunda:Connector * @param {Object} scopeDefinition */ function updateScopeElements(element, scopeName, scopeDefinition) { var scopeElement = bpmnFactory.create(scopeName); // update camunda:inputOutput updateIoMappings(element, scopeDefinition, scopeElement); // update camunda:field updateCamundaField(element, scopeDefinition, scopeElement); // update camunda:properties updateCamundaProperties(element, scopeDefinition, scopeElement); // update other properties (bpmn:condition, camunda:async, ...) updateProperties(element, scopeDefinition, scopeElement); // update camunda:in and camunda:out updateInOut(element, scopeDefinition, scopeElement); // update camunda:executionListener updateExecutionListener(element, scopeDefinition, scopeElement); var extensionElements = getOrCreateExtensionElements(element); var oldScope = findExtension(extensionElements, scopeName); commandStack.execute('properties-panel.update-businessobject-list', { element: element, currentObject: extensionElements, propertyName: 'values', objectsToAdd: [scopeElement], objectsToRemove: oldScope ? [oldScope] : [] }); } /** * Compose an element template change action, updating all * necessary underlying properties. * * @param {Object} context * @param {Object} context.element * @param {Object} context.oldTemplate * @param {Object} context.newTemplate */ this.preExecute = function (context) { var element = context.element, newTemplate = context.newTemplate; // update camunda:modelerTemplate attribute updateModelerTemplate(element, newTemplate); if (newTemplate) { // update camunda:inputOutput updateIoMappings(element, newTemplate); // update camunda:field updateCamundaField(element, newTemplate); // update camunda:properties updateCamundaProperties(element, newTemplate); // update other properties (bpmn:condition, camunda:async, ...) updateProperties(element, newTemplate); // update camunda:in and camunda:out updateInOut(element, newTemplate); // update camunda:executionListener updateExecutionListener(element, newTemplate); // loop on scopes properties forEach(newTemplate.scopes, function (scopeDefinition, scopeName) { updateScopeElements(element, scopeName, scopeDefinition); }); } }; } ChangeElementTemplateHandler.$inject = ['modeling', 'commandStack', 'bpmnFactory']; module.exports = ChangeElementTemplateHandler; /////// helpers ///////////////////////////// function createBpmnPropertyUpdates(template, bpmnFactory) { var propertyUpdates = {}; template.properties.forEach(function (p) { var binding = p.binding, bindingTarget = binding.name, propertyValue; if (binding.type === 'property') { if (bindingTarget === 'conditionExpression') { propertyValue = bpmnFactory.create('bpmn:FormalExpression', { body: p.value, language: binding.scriptFormat }); } else { propertyValue = p.value; } // assigning camunda:async to true|false // assigning bpmn:conditionExpression to { $type: 'bpmn:FormalExpression', ... } propertyUpdates[bindingTarget] = propertyValue; // make sure we unset other "implementation types" // when applying a camunda:class template onto a preconfigured // camunda:delegateExpression element if (CAMUNDA_SERVICE_TASK_LIKE.indexOf(bindingTarget) !== -1) { CAMUNDA_SERVICE_TASK_LIKE.forEach(function (prop) { if (prop !== bindingTarget) { propertyUpdates[prop] = undefined; } }); } } }); return propertyUpdates; } function createCamundaFieldInjections(template, bpmnFactory) { var injections = []; template.properties.forEach(function (p) { var binding = p.binding, bindingType = binding.type; if (bindingType === 'camunda:field') { injections.push(createCamundaFieldInjection(binding, p.value, bpmnFactory)); } }); if (injections.length) { return injections; } } function createCamundaProperties(template, bpmnFactory) { var properties = []; template.properties.forEach(function (p) { var binding = p.binding, bindingType = binding.type; if (bindingType === 'camunda:property') { properties.push(createCamundaProperty(binding, p.value, bpmnFactory)); } }); if (properties.length) { return bpmnFactory.create('camunda:Properties', { values: properties }); } } function createInputOutputMappings(template, bpmnFactory) { var inputParameters = [], outputParameters = []; template.properties.forEach(function (p) { var binding = p.binding, bindingType = binding.type; if (bindingType === 'camunda:inputParameter') { inputParameters.push(createInputParameter(binding, p.value, bpmnFactory)); } if (bindingType === 'camunda:outputParameter') { outputParameters.push(createOutputParameter(binding, p.value, bpmnFactory)); } }); // do we need to create new ioMappings (?) if (outputParameters.length || inputParameters.length) { return bpmnFactory.create('camunda:InputOutput', { inputParameters: inputParameters, outputParameters: outputParameters }); } } function createCamundaInOut(template, bpmnFactory) { var inOuts = []; template.properties.forEach(function (p) { var binding = p.binding, bindingType = binding.type; if (bindingType === 'camunda:in') { inOuts.push(createCamundaIn(binding, p.value, bpmnFactory)); } else if (bindingType === 'camunda:out') { inOuts.push(createCamundaOut(binding, p.value, bpmnFactory)); } else if (bindingType === 'camunda:in:businessKey') { inOuts.push(createCamundaInWithBusinessKey(binding, p.value, bpmnFactory)); } }); return inOuts; } function createCamundaExecutionListeners(template, bpmnFactory) { var executionListener = []; template.properties.forEach(function (p) { var binding = p.binding, bindingType = binding.type; if (bindingType === 'camunda:executionListener') { executionListener.push(createCamundaExecutionListenerScript(binding, p.value, bpmnFactory)); } }); return executionListener; } },{"../CreateHelper":51,"../Helper":55,"lodash/collection/forEach":422}],58:[function(require,module,exports){ 'use strict'; var ChangeElementTemplateHandler = require('./ChangeElementTemplateHandler'); var getTemplate = require('../Helper').getTemplate, getDefaultTemplate = require('../Helper').getDefaultTemplate; function registerHandlers(commandStack, elementTemplates, eventBus, elementRegistry) { commandStack.registerHandler('propertiesPanel.camunda.changeTemplate', ChangeElementTemplateHandler); // apply default element templates on shape creation eventBus.on(['commandStack.shape.create.postExecuted'], function (context) { applyDefaultTemplate(context.context.shape, elementTemplates, commandStack); }); // apply default element templates on connection creation eventBus.on(['commandStack.connection.create.postExecuted'], function (context) { applyDefaultTemplate(context.context.connection, elementTemplates, commandStack); }); } registerHandlers.$inject = ['commandStack', 'elementTemplates', 'eventBus', 'elementRegistry']; module.exports = { __init__: [registerHandlers] }; function applyDefaultTemplate(element, elementTemplates, commandStack) { if (!getTemplate(element, elementTemplates) && getDefaultTemplate(element, elementTemplates)) { var command = 'propertiesPanel.camunda.changeTemplate'; var commandContext = { element: element, newTemplate: getDefaultTemplate(element, elementTemplates) }; commandStack.execute(command, commandContext); } } },{"../Helper":55,"./ChangeElementTemplateHandler":57}],59:[function(require,module,exports){ 'use strict'; module.exports = { __depends__: [require('./cmd'), require('diagram-js/lib/i18n/translate')], __init__: ['customElementsPropertiesActivator', 'elementTemplatesLoader'], customElementsPropertiesActivator: ['type', require('./CustomElementsPropertiesActivator')], elementTemplates: ['type', require('./ElementTemplates')], elementTemplatesLoader: ['type', require('./ElementTemplatesLoader')] }; },{"./CustomElementsPropertiesActivator":52,"./ElementTemplates":53,"./ElementTemplatesLoader":54,"./cmd":58,"diagram-js/lib/i18n/translate":376}],60:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'), is = require('bpmn-js/lib/util/ModelUtil').is, getTemplate = require('../Helper').getTemplate, getTemplateId = require('../Helper').getTemplateId; var find = require('lodash/collection/find'); var TEMPLATE_ATTR = require('../Helper').TEMPLATE_ATTR; function isAny(element, types) { return types.reduce(function (result, type) { return result || is(element, type); }, false); } module.exports = function (group, element, elementTemplates, translate) { var options = getTemplateOptions(element, elementTemplates); if (options.length === 1 && !options[0].isDefault) { return; } // select element template (via dropdown) group.entries.push(entryFactory.selectBox({ id: 'elementTemplate-chooser', label: translate('Element Template'), modelProperty: 'camunda:modelerTemplate', selectOptions: options, set: function set(element, properties) { return applyTemplate(element, properties[TEMPLATE_ATTR], elementTemplates); }, disabled: function disabled() { var template = getTemplate(element, elementTemplates); return template && isDefaultTemplate(template); } })); }; ////// helpers ////////////////////////////////////// function applyTemplate(element, newTemplateId, elementTemplates) { // cleanup // clear input output mappings // undo changes to properties defined in template // re-establish // set input output mappings // apply changes to properties as defined in new template var oldTemplate = getTemplate(element, elementTemplates), newTemplate = elementTemplates.get(newTemplateId); if (oldTemplate === newTemplate) { return; } return { cmd: 'propertiesPanel.camunda.changeTemplate', context: { element: element, oldTemplate: oldTemplate, newTemplate: newTemplate } }; } function getTemplateOptions(element, elementTemplates) { var currentTemplateId = getTemplateId(element); var emptyOption = { name: '', value: '' }; var allOptions = elementTemplates.getAll().reduce(function (templates, t) { if (!isAny(element, t.appliesTo)) { return templates; } return templates.concat({ name: t.name, value: t.id, isDefault: t.isDefault }); }, [emptyOption]); var defaultOption = find(allOptions, function (option) { return isDefaultTemplate(option); }); var currentOption = find(allOptions, function (option) { return option.value === currentTemplateId; }); if (currentTemplateId && !currentOption) { currentOption = unknownTemplate(currentTemplateId); allOptions.push(currentOption); } if (!defaultOption) { // return all options, including empty // and optionally unknownTemplate option return allOptions; } // special limited handling for // default options var options = []; // current template not set if (!currentTemplateId) { options.push({ name: '', value: '' }); } // current template not default if (currentOption && currentOption !== defaultOption) { options.push(currentOption); } options.push(defaultOption); // [ (empty), (current), defaultOption ] return options; } function unknownTemplate(templateId) { return { name: '[unknown template: ' + templateId + ']', value: templateId }; } function isDefaultTemplate(elementTemplate) { return elementTemplate.isDefault; } },{"../../../../factory/EntryFactory":14,"../Helper":55,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/find":421}],61:[function(require,module,exports){ 'use strict'; var assign = require('lodash/object/assign'); var entryFactory = require('../../../../factory/EntryFactory'), getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, getTemplate = require('../Helper').getTemplate, cmdHelper = require('../../../../helper/CmdHelper'), elementHelper = require('../../../../helper/ElementHelper'); var findExtension = require('../Helper').findExtension, findExtensions = require('../Helper').findExtensions, findInputParameter = require('../Helper').findInputParameter, findOutputParameter = require('../Helper').findOutputParameter, findCamundaProperty = require('../Helper').findCamundaProperty, findCamundaInOut = require('../Helper').findCamundaInOut; var createCamundaProperty = require('../CreateHelper').createCamundaProperty, createInputParameter = require('../CreateHelper').createInputParameter, createOutputParameter = require('../CreateHelper').createOutputParameter, createCamundaIn = require('../CreateHelper').createCamundaIn, createCamundaOut = require('../CreateHelper').createCamundaOut, createCamundaInWithBusinessKey = require('../CreateHelper').createCamundaInWithBusinessKey, createCamundaFieldInjection = require('../CreateHelper').createCamundaFieldInjection; var CAMUNDA_PROPERTY_TYPE = 'camunda:property', CAMUNDA_INPUT_PARAMETER_TYPE = 'camunda:inputParameter', CAMUNDA_OUTPUT_PARAMETER_TYPE = 'camunda:outputParameter', CAMUNDA_IN_TYPE = 'camunda:in', CAMUNDA_OUT_TYPE = 'camunda:out', CAMUNDA_IN_BUSINESS_KEY_TYPE = 'camunda:in:businessKey', CAMUNDA_EXECUTION_LISTENER_TYPE = 'camunda:executionListener', CAMUNDA_FIELD = 'camunda:field'; var BASIC_MODDLE_TYPES = ['Boolean', 'Integer', 'String']; var EXTENSION_BINDING_TYPES = [CAMUNDA_PROPERTY_TYPE, CAMUNDA_INPUT_PARAMETER_TYPE, CAMUNDA_OUTPUT_PARAMETER_TYPE, CAMUNDA_IN_TYPE, CAMUNDA_OUT_TYPE, CAMUNDA_IN_BUSINESS_KEY_TYPE, CAMUNDA_FIELD]; var IO_BINDING_TYPES = [CAMUNDA_INPUT_PARAMETER_TYPE, CAMUNDA_OUTPUT_PARAMETER_TYPE]; var IN_OUT_BINDING_TYPES = [CAMUNDA_IN_TYPE, CAMUNDA_OUT_TYPE, CAMUNDA_IN_BUSINESS_KEY_TYPE]; /** * Injects custom properties into the given group. * * @param {GroupDescriptor} group * @param {djs.model.Base} element * @param {ElementTemplates} elementTemplates * @param {BpmnFactory} bpmnFactory */ module.exports = function (element, elementTemplates, bpmnFactory, translate) { var template = getTemplate(element, elementTemplates); if (!template) { return []; } var renderCustomField = function renderCustomField(id, p, idx) { var propertyType = p.type; var entryOptions = { id: id, description: p.description, label: p.label, modelProperty: id, get: propertyGetter(id, p), set: propertySetter(id, p, bpmnFactory), validate: propertyValidator(id, p) }; var entry; if (propertyType === 'Boolean') { entry = entryFactory.checkbox(entryOptions); } if (propertyType === 'String') { entry = entryFactory.textField(entryOptions); } if (propertyType === 'Text') { entry = entryFactory.textBox(entryOptions); } if (propertyType === 'Dropdown') { entryOptions.selectOptions = p.choices; entry = entryFactory.selectBox(entryOptions); } return entry; }; var groups = []; var id, entry; var customFieldsGroup = { id: 'customField', label: translate('Custom Fields'), entries: [] }; template.properties.forEach(function (p, idx) { id = 'custom-' + template.id + '-' + idx; entry = renderCustomField(id, p, idx); if (entry) { customFieldsGroup.entries.push(entry); } }); if (customFieldsGroup.entries.length > 0) { groups.push(customFieldsGroup); } if (template.scopes) { for (var scopeName in template.scopes) { var scope = template.scopes[scopeName]; var idScopeName = scopeName.replace(/:/g, '_'); var customScopeFieldsGroup = { id: 'customField-' + idScopeName, label: translate('Custom Fields for scope: ') + scopeName, entries: [] }; scope.properties.forEach(function (p, idx) { var propertyId = 'custom-' + template.id + '-' + idScopeName + '-' + idx; var scopedProperty = propertyWithScope(p, scopeName); entry = renderCustomField(propertyId, scopedProperty, idx); if (entry) { customScopeFieldsGroup.entries.push(entry); } }); if (customScopeFieldsGroup.entries.length > 0) { groups.push(customScopeFieldsGroup); } } } return groups; }; /////// getters, setters and validators /////////////// /** * Return a getter that retrieves the given property. * * @param {String} name * @param {PropertyDescriptor} property * * @return {Function} */ function propertyGetter(name, property) { /* getter */ return function get(element) { var value = getPropertyValue(element, property); return objectWithKey(name, value); }; } /** * Return a setter that updates the given property. * * @param {String} name * @param {PropertyDescriptor} property * @param {BpmnFactory} bpmnFactory * * @return {Function} */ function propertySetter(name, property, bpmnFactory) { /* setter */ return function set(element, values) { var value = values[name]; return setPropertyValue(element, property, value, bpmnFactory); }; } /** * Return a validator that ensures the property is ok. * * @param {String} name * @param {PropertyDescriptor} property * * @return {Function} */ function propertyValidator(name, property) { /* validator */ return function validate(element, values) { var value = values[name]; var error = validateValue(value, property); if (error) { return objectWithKey(name, error); } }; } //////// get, set and validate helpers /////////////////// /** * Return the value of the specified property descriptor, * on the passed diagram element. * * @param {djs.model.Base} element * @param {PropertyDescriptor} property * * @return {Any} */ function getPropertyValue(element, property) { var bo = getBusinessObject(element); var binding = property.binding, scope = property.scope; var bindingType = binding.type, bindingName = binding.name; var propertyValue = property.value || ''; if (scope) { bo = findExtension(bo, scope.name); if (!bo) { return propertyValue; } } // property if (bindingType === 'property') { var value = bo.get(bindingName); if (bindingName === 'conditionExpression') { if (value) { return value.body; } else { // return defined default return propertyValue; } } else { // return value; default to defined default return typeof value !== 'undefined' ? value : propertyValue; } } var camundaProperties, camundaProperty; if (bindingType === CAMUNDA_PROPERTY_TYPE) { if (scope) { camundaProperties = bo.get('properties'); } else { camundaProperties = findExtension(bo, 'camunda:Properties'); } if (camundaProperties) { camundaProperty = findCamundaProperty(camundaProperties, binding); if (camundaProperty) { return camundaProperty.value; } } return propertyValue; } var inputOutput, ioParameter; if (IO_BINDING_TYPES.indexOf(bindingType) !== -1) { if (scope) { inputOutput = bo.get('inputOutput'); } else { inputOutput = findExtension(bo, 'camunda:InputOutput'); } if (!inputOutput) { // ioParameter cannot exist yet, return property value return propertyValue; } } // camunda input parameter if (bindingType === CAMUNDA_INPUT_PARAMETER_TYPE) { ioParameter = findInputParameter(inputOutput, binding); if (ioParameter) { if (binding.scriptFormat) { if (ioParameter.definition) { return ioParameter.definition.value; } } else { return ioParameter.value || ''; } } return propertyValue; } // camunda output parameter if (binding.type === CAMUNDA_OUTPUT_PARAMETER_TYPE) { ioParameter = findOutputParameter(inputOutput, binding); if (ioParameter) { return ioParameter.name; } return propertyValue; } var ioElement; if (IN_OUT_BINDING_TYPES.indexOf(bindingType) != -1) { ioElement = findCamundaInOut(bo, binding); if (ioElement) { if (bindingType === CAMUNDA_IN_BUSINESS_KEY_TYPE) { return ioElement.businessKey; } else if (bindingType === CAMUNDA_OUT_TYPE) { return ioElement.target; } else if (bindingType === CAMUNDA_IN_TYPE) { return ioElement[binding.expression ? 'sourceExpression' : 'source']; } } return propertyValue; } if (bindingType === CAMUNDA_EXECUTION_LISTENER_TYPE) { var executionListener; if (scope) { executionListener = bo.get('executionListener'); } else { executionListener = findExtension(bo, 'camunda:ExecutionListener'); } return executionListener.script.value; } var fieldInjection; if (CAMUNDA_FIELD === bindingType) { var fieldInjections = findExtensions(bo, ['camunda:Field']); fieldInjections.forEach(function (item) { if (item.name === binding.name) { fieldInjection = item; } }); if (fieldInjection) { return fieldInjection.string || fieldInjection.expression; } else { return ''; } } throw unknownPropertyBinding(property); } module.exports.getPropertyValue = getPropertyValue; /** * Return an update operation that changes the diagram * element's custom property to the given value. * * The response of this method will be processed via * {@link PropertiesPanel#applyChanges}. * * @param {djs.model.Base} element * @param {PropertyDescriptor} property * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {Object|Array} results to be processed */ function setPropertyValue(element, property, value, bpmnFactory) { var bo = getBusinessObject(element); var binding = property.binding, scope = property.scope; var bindingType = binding.type, bindingName = binding.name; var propertyValue; var updates = []; var extensionElements; if (EXTENSION_BINDING_TYPES.indexOf(bindingType) !== -1) { extensionElements = bo.get('extensionElements'); // create extension elements, if they do not exist (yet) if (!extensionElements) { extensionElements = elementHelper.createElement('bpmn:ExtensionElements', null, element, bpmnFactory); updates.push(cmdHelper.updateBusinessObject(element, bo, objectWithKey('extensionElements', extensionElements))); } } if (scope) { bo = findExtension(bo, scope.name); if (!bo) { bo = elementHelper.createElement(scope.name, null, element, bpmnFactory); updates.push(cmdHelper.addElementsTolist(bo, extensionElements, 'values', [bo])); } } // property if (bindingType === 'property') { if (bindingName === 'conditionExpression') { propertyValue = elementHelper.createElement('bpmn:FormalExpression', { body: value, language: binding.scriptFormat }, bo, bpmnFactory); } else { var moddlePropertyDescriptor = bo.$descriptor.propertiesByName[bindingName]; var moddleType = moddlePropertyDescriptor.type; // make sure we only update String, Integer, Real and // Boolean properties (do not accidentally override complex objects...) if (BASIC_MODDLE_TYPES.indexOf(moddleType) === -1) { throw new Error('cannot set moddle type <' + moddleType + '>'); } if (moddleType === 'Boolean') { propertyValue = !!value; } else if (moddleType === 'Integer') { propertyValue = parseInt(value, 10); if (isNaN(propertyValue)) { // do not write NaN value propertyValue = undefined; } } else { propertyValue = value; } } if (propertyValue !== undefined) { updates.push(cmdHelper.updateBusinessObject(element, bo, objectWithKey(bindingName, propertyValue))); } } // camunda:property var camundaProperties, existingCamundaProperty, newCamundaProperty; if (bindingType === CAMUNDA_PROPERTY_TYPE) { if (scope) { camundaProperties = bo.get('properties'); } else { camundaProperties = findExtension(extensionElements, 'camunda:Properties'); } if (!camundaProperties) { camundaProperties = elementHelper.createElement('camunda:Properties', null, bo, bpmnFactory); if (scope) { updates.push(cmdHelper.updateBusinessObject(element, bo, { properties: camundaProperties })); } else { updates.push(cmdHelper.addElementsTolist(element, extensionElements, 'values', [camundaProperties])); } } existingCamundaProperty = findCamundaProperty(camundaProperties, binding); newCamundaProperty = createCamundaProperty(binding, value, bpmnFactory); updates.push(cmdHelper.addAndRemoveElementsFromList(element, camundaProperties, 'values', null, [newCamundaProperty], existingCamundaProperty ? [existingCamundaProperty] : [])); } // camunda:inputParameter // camunda:outputParameter var inputOutput, existingIoParameter, newIoParameter; if (IO_BINDING_TYPES.indexOf(bindingType) !== -1) { if (scope) { inputOutput = bo.get('inputOutput'); } else { inputOutput = findExtension(extensionElements, 'camunda:InputOutput'); } // create inputOutput element, if it do not exist (yet) if (!inputOutput) { inputOutput = elementHelper.createElement('camunda:InputOutput', null, bo, bpmnFactory); if (scope) { updates.push(cmdHelper.updateBusinessObject(element, bo, { inputOutput: inputOutput })); } else { updates.push(cmdHelper.addElementsTolist(element, extensionElements, 'values', inputOutput)); } } } if (bindingType === CAMUNDA_INPUT_PARAMETER_TYPE) { existingIoParameter = findInputParameter(inputOutput, binding); newIoParameter = createInputParameter(binding, value, bpmnFactory); updates.push(cmdHelper.addAndRemoveElementsFromList(element, inputOutput, 'inputParameters', null, [newIoParameter], existingIoParameter ? [existingIoParameter] : [])); } if (bindingType === CAMUNDA_OUTPUT_PARAMETER_TYPE) { existingIoParameter = findOutputParameter(inputOutput, binding); newIoParameter = createOutputParameter(binding, value, bpmnFactory); updates.push(cmdHelper.addAndRemoveElementsFromList(element, inputOutput, 'outputParameters', null, [newIoParameter], existingIoParameter ? [existingIoParameter] : [])); } // camunda:in // camunda:out // camunda:in:businessKey var existingInOut, newInOut; if (IN_OUT_BINDING_TYPES.indexOf(bindingType) !== -1) { existingInOut = findCamundaInOut(bo, binding); if (bindingType === CAMUNDA_IN_TYPE) { newInOut = createCamundaIn(binding, value, bpmnFactory); } else if (bindingType === CAMUNDA_OUT_TYPE) { newInOut = createCamundaOut(binding, value, bpmnFactory); } else { newInOut = createCamundaInWithBusinessKey(binding, value, bpmnFactory); } updates.push(cmdHelper.addAndRemoveElementsFromList(element, extensionElements, 'values', null, [newInOut], existingInOut ? [existingInOut] : [])); } if (bindingType === CAMUNDA_FIELD) { var existingFieldInjections = findExtensions(bo, ['camunda:Field']); var newFieldInjections = []; if (existingFieldInjections.length > 0) { existingFieldInjections.forEach(function (item) { if (item.name === binding.name) { newFieldInjections.push(createCamundaFieldInjection(binding, value, bpmnFactory)); } else { newFieldInjections.push(item); } }); } else { newFieldInjections.push(createCamundaFieldInjection(binding, value, bpmnFactory)); } updates.push(cmdHelper.addAndRemoveElementsFromList(element, extensionElements, 'values', null, newFieldInjections, existingFieldInjections ? existingFieldInjections : [])); } if (updates.length) { return updates; } // quick warning for better debugging console.warn('no update', element, property, value); } /** * Validate value of a given property. * * @param {String} value * @param {PropertyDescriptor} property * * @return {Object} with validation errors */ function validateValue(value, property) { var constraints = property.constraints || {}; if (constraints.notEmpty && isEmpty(value)) { return 'Must not be empty'; } if (constraints.maxLength && value.length > constraints.maxLength) { return 'Must have max length ' + constraints.maxLength; } if (constraints.minLength && value.length < constraints.minLength) { return 'Must have min length ' + constraints.minLength; } var pattern = constraints.pattern, message; if (pattern) { if (typeof pattern !== 'string') { message = pattern.message; pattern = pattern.value; } if (!matchesPattern(value, pattern)) { return message || 'Must match pattern ' + pattern; } } } //////// misc helpers /////////////////////////////// function propertyWithScope(property, scopeName) { if (!scopeName) { return property; } return assign({}, property, { scope: { name: scopeName } }); } /** * Return an object with a single key -> value association. * * @param {String} key * @param {Any} value * * @return {Object} */ function objectWithKey(key, value) { var obj = {}; obj[key] = value; return obj; } /** * Does the given string match the specified pattern? * * @param {String} str * @param {String} pattern * * @return {Boolean} */ function matchesPattern(str, pattern) { var regexp = new RegExp(pattern); return regexp.test(str); } function isEmpty(str) { return !str || /^\s*$/.test(str); } /** * Create a new {@link Error} indicating an unknown * property binding. * * @param {PropertyDescriptor} property * * @return {Error} */ function unknownPropertyBinding(property) { var binding = property.binding; return new Error('unknown binding: <' + binding.type + '>'); } },{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../CreateHelper":51,"../Helper":55,"bpmn-js/lib/util/ModelUtil":216,"lodash/object/assign":496}],62:[function(require,module,exports){ 'use strict'; module.exports = { __depends__: [require('./element-templates'), require('diagram-js/lib/i18n/translate')], __init__: ['propertiesProvider'], propertiesProvider: ['type', require('./CamundaPropertiesProvider')] }; },{"./CamundaPropertiesProvider":50,"./element-templates":59,"diagram-js/lib/i18n/translate":376}],63:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, is = require('bpmn-js/lib/util/ModelUtil').is, asyncContinuation = require('./implementation/AsyncContinuation'); module.exports = function (group, element, bpmnFactory, translate) { if (is(element, 'camunda:AsyncCapable')) { group.entries = group.entries.concat(asyncContinuation(element, bpmnFactory, { getBusinessObject: getBusinessObject }, translate)); } }; },{"./implementation/AsyncContinuation":87,"bpmn-js/lib/util/ModelUtil":216}],64:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, is = require('bpmn-js/lib/util/ModelUtil').is; var entryFactory = require('../../../factory/EntryFactory'); var callable = require('./implementation/Callable'); var cmdHelper = require('../../../helper/CmdHelper'); var flattenDeep = require('lodash/array/flattenDeep'); var assign = require('lodash/object/assign'); function getCallableType(element) { var bo = getBusinessObject(element); var boCalledElement = bo.get('calledElement'), boCaseRef = bo.get('camunda:caseRef'); var callActivityType = ''; if (typeof boCalledElement !== 'undefined') { callActivityType = 'bpmn'; } else if (typeof boCaseRef !== 'undefined') { callActivityType = 'cmmn'; } return callActivityType; } var DEFAULT_PROPS = { calledElement: undefined, 'camunda:calledElementBinding': 'latest', 'camunda:calledElementVersion': undefined, 'camunda:calledElementTenantId': undefined, 'camunda:variableMappingClass': undefined, 'camunda:variableMappingDelegateExpression': undefined, 'camunda:caseRef': undefined, 'camunda:caseBinding': 'latest', 'camunda:caseVersion': undefined, 'camunda:caseTenantId': undefined }; module.exports = function (group, element, bpmnFactory, translate) { if (!is(element, 'camunda:CallActivity')) { return; } group.entries.push(entryFactory.selectBox({ id: 'callActivity', label: translate('CallActivity Type'), selectOptions: [{ name: 'BPMN', value: 'bpmn' }, { name: 'CMMN', value: 'cmmn' }], emptyParameter: true, modelProperty: 'callActivityType', get: function get(element, node) { return { callActivityType: getCallableType(element) }; }, set: function set(element, values, node) { var type = values.callActivityType; var props = assign({}, DEFAULT_PROPS); if (type === 'bpmn') { props.calledElement = ''; } else if (type === 'cmmn') { props['camunda:caseRef'] = ''; } return cmdHelper.updateProperties(element, props); } })); group.entries.push(callable(element, bpmnFactory, { getCallableType: getCallableType }, translate)); group.entries = flattenDeep(group.entries); }; },{"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"./implementation/Callable":88,"bpmn-js/lib/util/ModelUtil":216,"lodash/array/flattenDeep":417,"lodash/object/assign":496}],65:[function(require,module,exports){ 'use strict'; var ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper'), InputOutputHelper = require('../../../helper/InputOutputHelper'); var entryFactory = require('../../../factory/EntryFactory'), cmdHelper = require('../../../helper/CmdHelper'); function getImplementationType(element) { return ImplementationTypeHelper.getImplementationType(element); } function getBusinessObject(element) { return ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element); } function getConnector(bo) { return InputOutputHelper.getConnector(bo); } function isConnector(element) { return getImplementationType(element) === 'connector'; } module.exports = function (group, element, bpmnFactory, translate) { group.entries.push(entryFactory.textField({ id: 'connectorId', label: translate('Connector Id'), modelProperty: 'connectorId', get: function get(element, node) { var bo = getBusinessObject(element); var connector = bo && getConnector(bo); var value = connector && connector.get('connectorId'); return { connectorId: value }; }, set: function set(element, values, node) { var bo = getBusinessObject(element); var connector = getConnector(bo); return cmdHelper.updateBusinessObject(element, connector, { connectorId: values.connectorId || undefined }); }, validate: function validate(element, values, node) { return isConnector(element) && !values.connectorId ? { connectorId: translate('Must provide a value') } : {}; }, hidden: function hidden(element, node) { return !isConnector(element); } })); }; },{"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"../../../helper/ImplementationTypeHelper":29,"../../../helper/InputOutputHelper":30}],66:[function(require,module,exports){ 'use strict'; var assign = require('lodash/object/assign'); var inputOutputParameter = require('./implementation/InputOutputParameter'); module.exports = function (group, element, bpmnFactory, options, translate) { options = assign({ idPrefix: 'connector-', insideConnector: true }, options); group.entries = group.entries.concat(inputOutputParameter(element, bpmnFactory, options, translate)); }; },{"./implementation/InputOutputParameter":97,"lodash/object/assign":496}],67:[function(require,module,exports){ 'use strict'; var inputOutput = require('./implementation/InputOutput'); module.exports = function (group, element, bpmnFactory, translate) { var inputOutputEntry = inputOutput(element, bpmnFactory, { idPrefix: 'connector-', insideConnector: true }, translate); group.entries = group.entries.concat(inputOutputEntry.entries); return { getSelectedParameter: inputOutputEntry.getSelectedParameter }; }; },{"./implementation/InputOutput":96}],68:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper'); var externalTaskPriority = require('./implementation/ExternalTaskPriority'); function getServiceTaskLikeBusinessObject(element) { var bo = ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element); // if the element is not a serviceTaskLike element, fetch the normal business object // This avoids the loss of the process / participant business object if (!bo) { bo = getBusinessObject(element); } return bo; } module.exports = function (group, element, bpmnFactory, translate) { var bo = getServiceTaskLikeBusinessObject(element); if (!bo) { return; } if (is(bo, 'camunda:TaskPriorized') || is(bo, 'bpmn:Participant') && bo.get('processRef')) { group.entries = group.entries.concat(externalTaskPriority(element, bpmnFactory, { getBusinessObject: function getBusinessObject(element) { if (!is(bo, 'bpmn:Participant')) { return bo; } return bo.get('processRef'); } }, translate)); } }; },{"../../../helper/ImplementationTypeHelper":29,"./implementation/ExternalTaskPriority":92,"bpmn-js/lib/util/ModelUtil":216}],69:[function(require,module,exports){ 'use strict'; var ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper'); var fieldInjection = require('./implementation/FieldInjection'); module.exports = function (group, element, bpmnFactory, translate) { var bo = ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element); if (!bo) { return; } var fieldInjectionEntry = fieldInjection(element, bpmnFactory, translate, { businessObject: bo }); if (fieldInjectionEntry && fieldInjectionEntry.length > 0) { group.entries = group.entries.concat(fieldInjectionEntry); } }; },{"../../../helper/ImplementationTypeHelper":29,"./implementation/FieldInjection":93}],70:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, getExtensionElements = require('../../../helper/ExtensionElementsHelper').getExtensionElements, extensionElements = require('./implementation/ExtensionElements'), properties = require('./implementation/Properties'), entryFactory = require('../../../factory/EntryFactory'), elementHelper = require('../../../helper/ElementHelper'), cmdHelper = require('../../../helper/CmdHelper'), formHelper = require('../../../helper/FormHelper'), utils = require('../../../Utils'), is = require('bpmn-js/lib/util/ModelUtil').is, find = require('lodash/collection/find'), each = require('lodash/collection/forEach'); function generateValueId() { return utils.nextId('Value_'); } /** * Generate a form field specific textField using entryFactory. * * @param {string} options.id * @param {string} options.label * @param {string} options.modelProperty * @param {function} options.validate * * @return {Object} an entryFactory.textField object */ function formFieldTextField(options, getSelectedFormField) { var id = options.id, label = options.label, modelProperty = options.modelProperty, validate = options.validate; return entryFactory.textField({ id: id, label: label, modelProperty: modelProperty, get: function get(element, node) { var selectedFormField = getSelectedFormField(element, node) || {}, values = {}; values[modelProperty] = selectedFormField[modelProperty]; return values; }, set: function set(element, values, node) { var commands = []; if (typeof options.set === 'function') { var cmd = options.set(element, values, node); if (cmd) { commands.push(cmd); } } var formField = getSelectedFormField(element, node), properties = {}; properties[modelProperty] = values[modelProperty] || undefined; commands.push(cmdHelper.updateBusinessObject(element, formField, properties)); return commands; }, hidden: function hidden(element, node) { return !getSelectedFormField(element, node); }, validate: validate }); } function ensureFormKeyAndDataSupported(element) { return is(element, 'bpmn:StartEvent') && !is(element.parent, 'bpmn:SubProcess') || is(element, 'bpmn:UserTask'); } module.exports = function (group, element, bpmnFactory, translate) { if (!ensureFormKeyAndDataSupported(element)) { return; } /** * Return the currently selected form field querying the form field select box * from the DOM. * * @param {djs.model.Base} element * @param {DOMElement} node - DOM element of any form field text input * * @return {ModdleElement} the currently selected form field */ function getSelectedFormField(element, node) { var selected = formFieldsEntry.getSelected(element, node.parentNode); if (selected.idx === -1) { return; } return formHelper.getFormField(element, selected.idx); } //[FormKey] form key text input field group.entries.push(entryFactory.textField({ id: 'form-key', label: translate('Form Key'), modelProperty: 'formKey', get: function get(element, node) { var bo = getBusinessObject(element); return { formKey: bo.get('camunda:formKey') }; }, set: function set(element, values, node) { var bo = getBusinessObject(element), formKey = values.formKey || undefined; return cmdHelper.updateBusinessObject(element, bo, { 'camunda:formKey': formKey }); } })); // [FormData] form field select box var formFieldsEntry = extensionElements(element, bpmnFactory, { id: 'form-fields', label: translate('Form Fields'), modelProperty: 'id', prefix: 'FormField', createExtensionElement: function createExtensionElement(element, extensionElements, value) { var bo = getBusinessObject(element), commands = []; if (!extensionElements) { extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory); commands.push(cmdHelper.updateProperties(element, { extensionElements: extensionElements })); } var formData = formHelper.getFormData(element); if (!formData) { formData = elementHelper.createElement('camunda:FormData', { fields: [] }, extensionElements, bpmnFactory); commands.push(cmdHelper.addAndRemoveElementsFromList(element, extensionElements, 'values', 'extensionElements', [formData], [])); } var field = elementHelper.createElement('camunda:FormField', { id: value }, formData, bpmnFactory); if (typeof formData.fields !== 'undefined') { commands.push(cmdHelper.addElementsTolist(element, formData, 'fields', [field])); } else { commands.push(cmdHelper.updateBusinessObject(element, formData, { fields: [field] })); } return commands; }, removeExtensionElement: function removeExtensionElement(element, extensionElements, value, idx) { var formData = getExtensionElements(getBusinessObject(element), 'camunda:FormData')[0], entry = formData.fields[idx], commands = []; commands.push(cmdHelper.removeElementsFromList(element, formData, 'fields', null, [entry])); if (entry.id === formData.get('businessKey')) { commands.push(cmdHelper.updateBusinessObject(element, formData, { 'businessKey': undefined })); } return commands; }, getExtensionElements: function getExtensionElements(element) { return formHelper.getFormFields(element); }, hideExtensionElements: function hideExtensionElements(element, node) { return false; } }); group.entries.push(formFieldsEntry); // [FormData] business key form field select box var formBusinessKeyFormFieldEntry = entryFactory.selectBox({ id: 'form-business-key', label: translate('Business Key'), modelProperty: 'businessKey', selectOptions: function selectOptions(element, inputNode) { var selectOptions = [{ name: '', value: '' }]; var formFields = formHelper.getFormFields(element); each(formFields, function (field) { if (field.type !== 'boolean') { selectOptions.push({ name: field.id, value: field.id }); } }); return selectOptions; }, get: function get(element, node) { var result = { businessKey: '' }; var bo = getBusinessObject(element); var formDataExtension = getExtensionElements(bo, 'camunda:FormData'); if (formDataExtension) { var formData = formDataExtension[0]; var storedValue = formData.get('businessKey'); result = { businessKey: storedValue }; } return result; }, set: function set(element, values, node) { var formData = getExtensionElements(getBusinessObject(element), 'camunda:FormData')[0]; return cmdHelper.updateBusinessObject(element, formData, { 'businessKey': values.businessKey || undefined }); }, hidden: function hidden(element, node) { var isStartEvent = is(element, 'bpmn:StartEvent'); return !(isStartEvent && formHelper.getFormFields(element).length > 0); } }); group.entries.push(formBusinessKeyFormFieldEntry); // [FormData] Form Field label group.entries.push(entryFactory.label({ id: 'form-field-header', labelText: translate('Form Field'), showLabel: function showLabel(element, node) { return !!getSelectedFormField(element, node); } })); // [FormData] form field id text input field group.entries.push(entryFactory.validationAwareTextField({ id: 'form-field-id', label: translate('ID'), modelProperty: 'id', getProperty: function getProperty(element, node) { var selectedFormField = getSelectedFormField(element, node) || {}; return selectedFormField.id; }, setProperty: function setProperty(element, properties, node) { var formField = getSelectedFormField(element, node); return cmdHelper.updateBusinessObject(element, formField, properties); }, hidden: function hidden(element, node) { return !getSelectedFormField(element, node); }, validate: function validate(element, values, node) { var formField = getSelectedFormField(element, node); if (formField) { var idValue = values.id; if (!idValue || idValue.trim() === '') { return { id: 'Form field id must not be empty' }; } var formFields = formHelper.getFormFields(element); var existingFormField = find(formFields, function (f) { return f !== formField && f.id === idValue; }); if (existingFormField) { return { id: 'Form field id already used in form data.' }; } } } })); // [FormData] form field type combo box group.entries.push(entryFactory.comboBox({ id: 'form-field-type', label: translate('Type'), selectOptions: [{ name: 'string', value: 'string' }, { name: 'long', value: 'long' }, { name: 'boolean', value: 'boolean' }, { name: 'date', value: 'date' }, { name: 'enum', value: 'enum' }], modelProperty: 'type', emptyParameter: true, get: function get(element, node) { var selectedFormField = getSelectedFormField(element, node); if (selectedFormField) { return { type: selectedFormField.type }; } else { return {}; } }, set: function set(element, values, node) { var selectedFormField = getSelectedFormField(element, node), formData = getExtensionElements(getBusinessObject(element), 'camunda:FormData')[0], commands = []; if (selectedFormField.type === 'enum' && values.type !== 'enum') { // delete camunda:value objects from formField.values when switching from type enum commands.push(cmdHelper.updateBusinessObject(element, selectedFormField, { values: undefined })); } if (values.type === 'boolean' && selectedFormField.get('id') === formData.get('businessKey')) { commands.push(cmdHelper.updateBusinessObject(element, formData, { 'businessKey': undefined })); } commands.push(cmdHelper.updateBusinessObject(element, selectedFormField, values)); return commands; }, hidden: function hidden(element, node) { return !getSelectedFormField(element, node); } })); // [FormData] form field label text input field group.entries.push(formFieldTextField({ id: 'form-field-label', label: translate('Label'), modelProperty: 'label' }, getSelectedFormField)); // [FormData] form field defaultValue text input field group.entries.push(formFieldTextField({ id: 'form-field-defaultValue', label: translate('Default Value'), modelProperty: 'defaultValue' }, getSelectedFormField)); // [FormData] form field enum values label group.entries.push(entryFactory.label({ id: 'form-field-enum-values-header', labelText: translate('Values'), divider: true, showLabel: function showLabel(element, node) { var selectedFormField = getSelectedFormField(element, node); return selectedFormField && selectedFormField.type === 'enum'; } })); // [FormData] form field enum values table group.entries.push(entryFactory.table({ id: 'form-field-enum-values', labels: [translate('Id'), translate('Name')], modelProperties: ['id', 'name'], show: function show(element, node) { var selectedFormField = getSelectedFormField(element, node); return selectedFormField && selectedFormField.type === 'enum'; }, getElements: function getElements(element, node) { var selectedFormField = getSelectedFormField(element, node); return formHelper.getEnumValues(selectedFormField); }, addElement: function addElement(element, node) { var selectedFormField = getSelectedFormField(element, node), id = generateValueId(); var enumValue = elementHelper.createElement('camunda:Value', { id: id, name: undefined }, getBusinessObject(element), bpmnFactory); return cmdHelper.addElementsTolist(element, selectedFormField, 'values', [enumValue]); }, removeElement: function removeElement(element, node, idx) { var selectedFormField = getSelectedFormField(element, node), enumValue = selectedFormField.values[idx]; return cmdHelper.removeElementsFromList(element, selectedFormField, 'values', null, [enumValue]); }, updateElement: function updateElement(element, value, node, idx) { var selectedFormField = getSelectedFormField(element, node), enumValue = selectedFormField.values[idx]; value.name = value.name || undefined; return cmdHelper.updateBusinessObject(element, enumValue, value); }, validate: function validate(element, value, node, idx) { var selectedFormField = getSelectedFormField(element, node), enumValue = selectedFormField.values[idx]; if (enumValue) { // check if id is valid var validationError = utils.isIdValid(enumValue, value.id); if (validationError) { return { id: validationError }; } } } })); // [FormData] Validation label group.entries.push(entryFactory.label({ id: 'form-field-validation-header', labelText: translate('Validation'), divider: true, showLabel: function showLabel(element, node) { return !!getSelectedFormField(element, node); } })); // [FormData] form field constraints table group.entries.push(entryFactory.table({ id: 'constraints-list', modelProperties: ['name', 'config'], labels: [translate('Name'), translate('Config')], addLabel: translate('Add Constraint'), getElements: function getElements(element, node) { var formField = getSelectedFormField(element, node); return formHelper.getConstraints(formField); }, addElement: function addElement(element, node) { var commands = [], formField = getSelectedFormField(element, node), validation = formField.validation; if (!validation) { // create validation business object and add it to form data, if it doesn't exist validation = elementHelper.createElement('camunda:Validation', {}, getBusinessObject(element), bpmnFactory); commands.push(cmdHelper.updateBusinessObject(element, formField, { 'validation': validation })); } var newConstraint = elementHelper.createElement('camunda:Constraint', { name: undefined, config: undefined }, validation, bpmnFactory); commands.push(cmdHelper.addElementsTolist(element, validation, 'constraints', [newConstraint])); return commands; }, updateElement: function updateElement(element, value, node, idx) { var formField = getSelectedFormField(element, node), constraint = formHelper.getConstraints(formField)[idx]; value.name = value.name || undefined; value.config = value.config || undefined; return cmdHelper.updateBusinessObject(element, constraint, value); }, removeElement: function removeElement(element, node, idx) { var commands = [], formField = getSelectedFormField(element, node), constraints = formHelper.getConstraints(formField), currentConstraint = constraints[idx]; commands.push(cmdHelper.removeElementsFromList(element, formField.validation, 'constraints', null, [currentConstraint])); if (constraints.length === 1) { // remove camunda:validation if the last existing constraint has been removed commands.push(cmdHelper.updateBusinessObject(element, formField, { validation: undefined })); } return commands; }, show: function show(element, node) { return !!getSelectedFormField(element, node); } })); // [FormData] Properties label group.entries.push(entryFactory.label({ id: 'form-field-properties-header', labelText: translate('Properties'), divider: true, showLabel: function showLabel(element, node) { return !!getSelectedFormField(element, node); } })); // [FormData] camunda:properties table group.entries.push(properties(element, bpmnFactory, { id: 'form-field-properties', modelProperties: ['id', 'value'], labels: [translate('Id'), translate('Value')], getParent: function getParent(element, node) { return getSelectedFormField(element, node); }, show: function show(element, node) { return !!getSelectedFormField(element, node); } }, translate)); }; },{"../../../Utils":5,"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"../../../helper/ElementHelper":25,"../../../helper/ExtensionElementsHelper":27,"../../../helper/FormHelper":28,"./implementation/ExtensionElements":90,"./implementation/Properties":102,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/find":421,"lodash/collection/forEach":422}],71:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, _getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var historyTimeToLive = require('./implementation/HistoryTimeToLive'); module.exports = function (group, element, bpmnFactory, translate) { var businessObject = _getBusinessObject(element); if (is(element, 'camunda:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) { group.entries = group.entries.concat(historyTimeToLive(element, bpmnFactory, { getBusinessObject: function getBusinessObject(element) { var bo = _getBusinessObject(element); if (!is(bo, 'bpmn:Participant')) { return bo; } return bo.get('processRef'); } }, translate)); } }; },{"./implementation/HistoryTimeToLive":94,"bpmn-js/lib/util/ModelUtil":216}],72:[function(require,module,exports){ 'use strict'; var inputOutputParameter = require('./implementation/InputOutputParameter'); var assign = require('lodash/object/assign'); module.exports = function (group, element, bpmnFactory, options, translate) { group.entries = group.entries.concat(inputOutputParameter(element, bpmnFactory, assign({}, options), translate)); }; },{"./implementation/InputOutputParameter":97,"lodash/object/assign":496}],73:[function(require,module,exports){ 'use strict'; var inputOutput = require('./implementation/InputOutput'); module.exports = function (group, element, bpmnFactory, translate) { var inputOutputEntry = inputOutput(element, bpmnFactory, {}, translate); group.entries = group.entries.concat(inputOutputEntry.entries); return { getSelectedParameter: inputOutputEntry.getSelectedParameter }; }; },{"./implementation/InputOutput":96}],74:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, _getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var jobPriority = require('./implementation/JobPriority'), jobRetryTimeCycle = require('./implementation/JobRetryTimeCycle'); module.exports = function (group, element, bpmnFactory, translate) { var businessObject = _getBusinessObject(element); if (is(element, 'camunda:JobPriorized') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) { group.entries = group.entries.concat(jobPriority(element, bpmnFactory, { getBusinessObject: function getBusinessObject(element) { var bo = _getBusinessObject(element); if (!is(bo, 'bpmn:Participant')) { return bo; } return bo.get('processRef'); } }, translate)); } if (is(element, 'camunda:AsyncCapable')) { group.entries = group.entries.concat(jobRetryTimeCycle(element, bpmnFactory, { getBusinessObject: _getBusinessObject }, translate)); } }; },{"./implementation/JobPriority":98,"./implementation/JobRetryTimeCycle":99,"bpmn-js/lib/util/ModelUtil":216}],75:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../factory/EntryFactory'); var cmdHelper = require('../../../helper/CmdHelper'), ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper'), script = require('./implementation/Script')('scriptFormat', 'value', true); var LISTENER_TYPE_LABEL = { class: 'Java Class', expression: 'Expression', delegateExpression: 'Delegate Expression', script: 'Script' }; module.exports = function (group, element, bpmnFactory, options, translate) { options = options || {}; var getSelectedListener = options.getSelectedListener; var classProp = 'class', expressionProp = 'expression', delegateExpressionProp = 'delegateExpression', scriptProp = 'script'; var executionListenerEventTypeOptions = ImplementationTypeHelper.isSequenceFlow(element) ? [{ name: 'take', value: 'take' }] : [{ name: 'start', value: 'start' }, { name: 'end', value: 'end' }]; var taskListenerEventTypeOptions = [{ name: 'create', value: 'create' }, { name: 'assignment', value: 'assignment' }, { name: 'complete', value: 'complete' }, { name: 'delete', value: 'delete' }]; var isSelected = function isSelected(element, node) { return getSelectedListener(element, node); }; group.entries.push(entryFactory.selectBox({ id: 'listener-event-type', label: translate('Event Type'), modelProperty: 'eventType', emptyParameter: false, get: function get(element, node) { var listener = getSelectedListener(element, node); var eventType = listener && listener.get('event'); return { eventType: eventType }; }, set: function set(element, values, node) { var eventType = values.eventType; return cmdHelper.updateBusinessObject(element, getSelectedListener(element, node), { event: eventType }); }, selectOptions: function selectOptions(element, node) { var eventTypeOptions; var selectedListener = getSelectedListener(element, node); if (ImplementationTypeHelper.isTaskListener(selectedListener)) { eventTypeOptions = taskListenerEventTypeOptions; } else if (ImplementationTypeHelper.isExecutionListener(selectedListener)) { eventTypeOptions = executionListenerEventTypeOptions; } return eventTypeOptions; }, hidden: function hidden(element, node) { return !isSelected(element, node); } })); group.entries.push(entryFactory.selectBox({ id: 'listener-type', label: translate('Listener Type'), selectOptions: [{ value: classProp, name: translate('Java Class') }, { value: expressionProp, name: translate('Expression') }, { value: delegateExpressionProp, name: translate('Delegate Expression') }, { value: scriptProp, name: translate('Script') }], modelProperty: 'listenerType', emptyParameter: false, get: function get(element, node) { var listener = getSelectedListener(element, node); return { listenerType: ImplementationTypeHelper.getImplementationType(listener) }; }, set: function set(element, values, node) { var listener = getSelectedListener(element, node), listenerType = values.listenerType || undefined, update = {}; update[classProp] = listenerType === classProp ? '' : undefined; update[expressionProp] = listenerType === expressionProp ? '' : undefined; update[delegateExpressionProp] = listenerType === delegateExpressionProp ? '' : undefined; update[scriptProp] = listenerType === scriptProp ? bpmnFactory.create('camunda:Script') : undefined; return cmdHelper.updateBusinessObject(element, listener, update); }, hidden: function hidden(element, node) { return !isSelected(element, node); } })); group.entries.push(entryFactory.textField({ id: 'listener-value', dataValueLabel: 'listenerValueLabel', modelProperty: 'listenerValue', get: function get(element, node) { var value = {}, listener = getSelectedListener(element, node), listenerType = ImplementationTypeHelper.getImplementationType(listener); value.listenerValueLabel = LISTENER_TYPE_LABEL[listenerType] || ''; value.listenerValue = listener && listener.get(listenerType) || undefined; return value; }, set: function set(element, values, node) { var update = {}, listener = getSelectedListener(element, node), listenerType = ImplementationTypeHelper.getImplementationType(listener); update[listenerType] = values.listenerValue || ''; return cmdHelper.updateBusinessObject(element, listener, update); }, hidden: function hidden(element, node) { var listener = getSelectedListener(element, node); return !listener || listener.script; }, validate: function validate(element, values) { var value = values.listenerValue, validate = {}; if (!value) { validate.listenerValue = translate('Must provide a value'); } return validate; } })); group.entries.push({ id: 'listener-script-value', html: '
' + script.template + '
', get: function get(element, node) { var listener = getSelectedListener(element, node); return listener && listener.script ? script.get(element, listener.script) : {}; }, set: function set(element, values, node) { var listener = getSelectedListener(element, node); var update = script.set(element, values, listener); return cmdHelper.updateBusinessObject(element, listener.script, update); }, validate: function validate(element, values, node) { var listener = getSelectedListener(element, node); return listener && listener.script ? script.validate(element, values) : {}; }, isScript: function isScript(element, node) { var listener = getSelectedListener(element, node); return listener && listener.script; }, script: script }); }; },{"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"../../../helper/ImplementationTypeHelper":29,"./implementation/Script":104}],76:[function(require,module,exports){ 'use strict'; var assign = require('lodash/object/assign'); var fieldInjection = require('./implementation/FieldInjection'); module.exports = function (group, element, bpmnFactory, options, translate) { options = assign({ idPrefix: 'listener-', insideListener: true }, options); var fieldInjectionEntry = fieldInjection(element, bpmnFactory, translate, options); if (fieldInjectionEntry && fieldInjectionEntry.length > 0) { group.entries = group.entries.concat(fieldInjectionEntry); } }; },{"./implementation/FieldInjection":93,"lodash/object/assign":496}],77:[function(require,module,exports){ 'use strict'; var listener = require('./implementation/Listener'); module.exports = function (group, element, bpmnFactory, translate) { var listenerEntry = listener(element, bpmnFactory, {}, translate); group.entries = group.entries.concat(listenerEntry.entries); return { getSelectedListener: listenerEntry.getSelectedListener }; }; },{"./implementation/Listener":100}],78:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, is = require('bpmn-js/lib/util/ModelUtil').is; var multiInstanceLoopCharacteristics = require('./implementation/MultiInstanceLoopCharacteristics'); var jobRetryTimeCycle = require('./implementation/JobRetryTimeCycle'), asyncContinuation = require('./implementation/AsyncContinuation'); function getLoopCharacteristics(element) { var bo = getBusinessObject(element); return bo.loopCharacteristics; } function ensureMultiInstanceSupported(element) { var loopCharacteristics = getLoopCharacteristics(element); return !!loopCharacteristics && is(loopCharacteristics, 'camunda:Collectable'); } module.exports = function (group, element, bpmnFactory, translate) { if (!ensureMultiInstanceSupported(element)) { return; } // multi instance properties group.entries = group.entries.concat(multiInstanceLoopCharacteristics(element, bpmnFactory, translate)); // async continuation /////////////////////////////////////////////////////// group.entries = group.entries.concat(asyncContinuation(element, bpmnFactory, { getBusinessObject: getLoopCharacteristics, idPrefix: 'multiInstance-', labelPrefix: translate('Multi Instance ') }, translate)); // retry time cycle ////////////////////////////////////////////////////////// group.entries = group.entries.concat(jobRetryTimeCycle(element, bpmnFactory, { getBusinessObject: getLoopCharacteristics, idPrefix: 'multiInstance-', labelPrefix: translate('Multi Instance ') }, translate)); }; },{"./implementation/AsyncContinuation":87,"./implementation/JobRetryTimeCycle":99,"./implementation/MultiInstanceLoopCharacteristics":101,"bpmn-js/lib/util/ModelUtil":216}],79:[function(require,module,exports){ 'use strict'; var properties = require('./implementation/Properties'), elementHelper = require('../../../helper/ElementHelper'), cmdHelper = require('../../../helper/CmdHelper'); module.exports = function (group, element, bpmnFactory, translate) { var propertiesEntry = properties(element, bpmnFactory, { id: 'properties', modelProperties: ['name', 'value'], labels: [translate('Name'), translate('Value')], getParent: function getParent(element, node, bo) { return bo.extensionElements; }, createParent: function createParent(element, bo) { var parent = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory); var cmd = cmdHelper.updateBusinessObject(element, bo, { extensionElements: parent }); return { cmd: cmd, parent: parent }; } }, translate); if (propertiesEntry) { group.entries.push(propertiesEntry); } }; },{"../../../helper/CmdHelper":24,"../../../helper/ElementHelper":25,"./implementation/Properties":102}],80:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, is = require('bpmn-js/lib/util/ModelUtil').is, entryFactory = require('../../../factory/EntryFactory'), cmdHelper = require('../../../helper/CmdHelper'), script = require('./implementation/Script')('scriptFormat', 'script', false); module.exports = function (group, element, bpmnFactory, translate) { var bo; if (is(element, 'bpmn:ScriptTask')) { bo = getBusinessObject(element); } if (!bo) { return; } group.entries.push({ id: 'script-implementation', label: translate('Script'), html: script.template, get: function get(element) { return script.get(element, bo); }, set: function set(element, values, containerElement) { var properties = script.set(element, values, containerElement); return cmdHelper.updateProperties(element, properties); }, validate: function validate(element, values) { return script.validate(element, values); }, script: script, cssClasses: ['bpp-textfield'] }); group.entries.push(entryFactory.textField({ id: 'scriptResultVariable', label: translate('Result Variable'), modelProperty: 'scriptResultVariable', get: function get(element, propertyName) { var boResultVariable = bo.get('camunda:resultVariable'); return { scriptResultVariable: boResultVariable }; }, set: function set(element, values, containerElement) { return cmdHelper.updateProperties(element, { 'camunda:resultVariable': values.scriptResultVariable.length ? values.scriptResultVariable : undefined }); } })); }; },{"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"./implementation/Script":104,"bpmn-js/lib/util/ModelUtil":216}],81:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, isAny = require('bpmn-js/lib/features/modeling/util/ModelingUtil').isAny, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, domQuery = require('min-dom/lib/query'), cmdHelper = require('../../../helper/CmdHelper'), elementHelper = require('../../../helper/ElementHelper'), script = require('./implementation/Script')('language', 'body', true); module.exports = function (group, element, bpmnFactory, translate) { var bo; if (is(element, 'bpmn:SequenceFlow')) { bo = getBusinessObject(element); } if (!bo) { return; } if (!isConditionalSource(element.source)) { return; } group.entries.push({ id: 'condition', label: translate('Condition'), html: '
' + '' + '
' + '' + '
' + '
' + // expression '
' + '' + '
' + '' + '' + '
' + '
' + script.template + '
' + '
', get: function get(element, propertyName) { // read values from xml: var conditionExpression = bo.conditionExpression; var values = {}, conditionType = ''; if (conditionExpression) { var conditionLanguage = conditionExpression.language; if (typeof conditionLanguage !== 'undefined') { conditionType = 'script'; values = script.get(element, conditionExpression); } else { conditionType = 'expression'; values.condition = conditionExpression.get('body'); } } values.conditionType = conditionType; return values; }, set: function set(element, values, containerElement) { var conditionType = values.conditionType; var commands = []; var conditionProps = { body: undefined }; if (conditionType === 'script') { conditionProps = script.set(element, values, containerElement); } else { var condition = values.condition; conditionProps.body = condition; } var update = { 'conditionExpression': undefined }; if (conditionType) { update.conditionExpression = elementHelper.createElement('bpmn:FormalExpression', conditionProps, bo, bpmnFactory); var source = element.source; // if default-flow, remove default-property from source if (source.businessObject.default === bo) { commands.push(cmdHelper.updateProperties(source, { 'default': undefined })); } } commands.push(cmdHelper.updateBusinessObject(element, bo, update)); return commands; }, validate: function validate(element, values) { var validationResult = {}; if (!values.condition && values.conditionType === 'expression') { validationResult.condition = 'Must provide a value'; } else if (values.conditionType === 'script') { validationResult = script.validate(element, values); } return validationResult; }, isExpression: function isExpression(element, inputNode) { var conditionType = domQuery('select[name=conditionType]', inputNode); if (conditionType.selectedIndex >= 0) { return conditionType.options[conditionType.selectedIndex].value === 'expression'; } }, isScript: function isScript(element, inputNode) { var conditionType = domQuery('select[name=conditionType]', inputNode); if (conditionType.selectedIndex >= 0) { return conditionType.options[conditionType.selectedIndex].value === 'script'; } }, clear: function clear(element, inputNode) { // clear text input domQuery('input[name=condition]', inputNode).value = ''; return true; }, canClear: function canClear(element, inputNode) { var input = domQuery('input[name=condition]', inputNode); return input.value !== ''; }, script: script, cssClasses: ['bpp-textfield'] }); }; ////// utilities ////////////////////////// var CONDITIONAL_SOURCES = ['bpmn:Activity', 'bpmn:ExclusiveGateway', 'bpmn:InclusiveGateway', 'bpmn:ComplexGateway']; function isConditionalSource(element) { return isAny(element, CONDITIONAL_SOURCES); } },{"../../../helper/CmdHelper":24,"../../../helper/ElementHelper":25,"./implementation/Script":104,"bpmn-js/lib/features/modeling/util/ModelingUtil":189,"bpmn-js/lib/util/ModelUtil":216,"min-dom/lib/query":112}],82:[function(require,module,exports){ 'use strict'; var ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper'), InputOutputHelper = require('../../../helper/InputOutputHelper'); var implementationType = require('./implementation/ImplementationType'), delegate = require('./implementation/Delegate'), external = require('./implementation/External'), callable = require('./implementation/Callable'), resultVariable = require('./implementation/ResultVariable'); var entryFactory = require('../../../factory/EntryFactory'); var domQuery = require('min-dom/lib/query'), domClosest = require('min-dom/lib/closest'), domClasses = require('min-dom/lib/classes'); function getImplementationType(element) { return ImplementationTypeHelper.getImplementationType(element); } function getBusinessObject(element) { return ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element); } function isDmnCapable(element) { return ImplementationTypeHelper.isDmnCapable(element); } function isExternalCapable(element) { return ImplementationTypeHelper.isExternalCapable(element); } function isServiceTaskLike(element) { return ImplementationTypeHelper.isServiceTaskLike(element); } module.exports = function (group, element, bpmnFactory, translate) { if (!isServiceTaskLike(getBusinessObject(element))) { return; } var hasDmnSupport = isDmnCapable(element); var hasExternalSupport = isExternalCapable(getBusinessObject(element)); // implementation type //////////////////////////////////// group.entries = group.entries.concat(implementationType(element, bpmnFactory, { getBusinessObject: getBusinessObject, getImplementationType: getImplementationType, hasDmnSupport: hasDmnSupport, hasExternalSupport: hasExternalSupport, hasServiceTaskLikeSupport: true }, translate)); // delegate (class, expression, delegateExpression) ////////// group.entries = group.entries.concat(delegate(element, bpmnFactory, { getBusinessObject: getBusinessObject, getImplementationType: getImplementationType }, translate)); // result variable ///////////////////////////////////////// group.entries = group.entries.concat(resultVariable(element, bpmnFactory, { getBusinessObject: getBusinessObject, getImplementationType: getImplementationType, hideResultVariable: function hideResultVariable(element, node) { return getImplementationType(element) !== 'expression'; } }, translate)); // external ////////////////////////////////////////////////// if (hasExternalSupport) { group.entries = group.entries.concat(external(element, bpmnFactory, { getBusinessObject: getBusinessObject, getImplementationType: getImplementationType }, translate)); } // dmn //////////////////////////////////////////////////////// if (hasDmnSupport) { group.entries = group.entries.concat(callable(element, bpmnFactory, { getCallableType: getImplementationType }, translate)); } // connector //////////////////////////////////////////////// var isConnector = function isConnector(element) { return getImplementationType(element) === 'connector'; }; group.entries.push(entryFactory.link({ id: 'configureConnectorLink', label: translate('Configure Connector'), getClickableElement: function getClickableElement(element, node) { var panel = domClosest(node, 'div.bpp-properties-panel'); return domQuery('a[data-tab-target="connector"]', panel); }, hideLink: function hideLink(element, node) { var link = domQuery('a', node); link.innerHTML = link.textContent = ''; domClasses(link).remove('bpp-error-message'); if (isConnector(element)) { var connectorId = InputOutputHelper.getConnector(element).get('connectorId'); if (connectorId) { link.textContent = translate('Configure Connector'); } else { link.innerHTML = ' Must configure Connector'; domClasses(link).add('bpp-error-message'); } return false; } return true; } })); }; },{"../../../factory/EntryFactory":14,"../../../helper/ImplementationTypeHelper":29,"../../../helper/InputOutputHelper":30,"./implementation/Callable":88,"./implementation/Delegate":89,"./implementation/External":91,"./implementation/ImplementationType":95,"./implementation/ResultVariable":103,"min-dom/lib/classes":106,"min-dom/lib/closest":108,"min-dom/lib/query":112}],83:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../factory/EntryFactory'), is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; module.exports = function (group, element, translate) { var bo = getBusinessObject(element); if (!bo) { return; } if (is(element, 'camunda:Initiator') && !is(element.parent, 'bpmn:SubProcess')) { group.entries.push(entryFactory.textField({ id: 'initiator', label: translate('Initiator'), modelProperty: 'initiator' })); } }; },{"../../../factory/EntryFactory":14,"bpmn-js/lib/util/ModelUtil":216}],84:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, entryFactory = require('../../../factory/EntryFactory'); module.exports = function (group, element, translate) { if (is(element, 'camunda:Assignable')) { // Assignee group.entries.push(entryFactory.textField({ id: 'assignee', label: translate('Assignee'), modelProperty: 'assignee' })); // Candidate Users group.entries.push(entryFactory.textField({ id: 'candidateUsers', label: translate('Candidate Users'), modelProperty: 'candidateUsers' })); // Candidate Groups group.entries.push(entryFactory.textField({ id: 'candidateGroups', label: translate('Candidate Groups'), modelProperty: 'candidateGroups' })); // Due Date group.entries.push(entryFactory.textField({ id: 'dueDate', description: translate('The due date as an EL expression (e.g. ${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)'), label: translate('Due Date'), modelProperty: 'dueDate' })); // FollowUp Date group.entries.push(entryFactory.textField({ id: 'followUpDate', description: translate('The follow up date as an EL expression (e.g. ${someDate} or an ' + 'ISO date (e.g. 2015-06-26T09:54:00)'), label: translate('Follow Up Date'), modelProperty: 'followUpDate' })); // priority group.entries.push(entryFactory.textField({ id: 'priority', label: translate('Priority'), modelProperty: 'priority' })); } }; },{"../../../factory/EntryFactory":14,"bpmn-js/lib/util/ModelUtil":216}],85:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var filter = require('lodash/collection/filter'); var extensionElementsHelper = require('../../../helper/ExtensionElementsHelper'), cmdHelper = require('../../../helper/CmdHelper'), elementHelper = require('../../../helper/ElementHelper'); var extensionElementsEntry = require('./implementation/ExtensionElements'); var entryFactory = require('../../../factory/EntryFactory'); var inOutTypeOptions = [{ name: 'Source', value: 'source' }, { name: 'Source Expression', value: 'sourceExpression' }, { name: 'All', value: 'variables' }]; /** * return depend on parameter 'type' camunda:in or camunda:out extension elements */ function getCamundaInOutMappings(element, type) { var bo = getBusinessObject(element); return extensionElementsHelper.getExtensionElements(bo, type) || []; } /** * return depend on parameter 'type' camunda:in or camunda:out extension elements * with source or sourceExpression attribute */ function getVariableMappings(element, type) { var camundaMappings = getCamundaInOutMappings(element, type); return filter(camundaMappings, function (mapping) { return !mapping.businessKey; }); } function getInOutType(mapping) { var inOutType = 'source'; if (mapping.variables === 'all') { inOutType = 'variables'; } else if (typeof mapping.source !== 'undefined') { inOutType = 'source'; } else if (typeof mapping.sourceExpression !== 'undefined') { inOutType = 'sourceExpression'; } return inOutType; } var CAMUNDA_IN_EXTENSION_ELEMENT = 'camunda:In', CAMUNDA_OUT_EXTENSION_ELEMENT = 'camunda:Out'; module.exports = function (group, element, bpmnFactory, translate) { if (!is(element, 'camunda:CallActivity')) { return; } var isSelected = function isSelected(element, node) { return !!getSelected(element, node); }; var getSelected = function getSelected(element, node) { var parentNode = node.parentNode; var selection = inEntry.getSelected(element, parentNode); var parameter = getVariableMappings(element, CAMUNDA_IN_EXTENSION_ELEMENT)[selection.idx]; if (!parameter && outEntry) { selection = outEntry.getSelected(element, parentNode); parameter = getVariableMappings(element, CAMUNDA_OUT_EXTENSION_ELEMENT)[selection.idx]; } return parameter; }; var setOptionLabelValue = function setOptionLabelValue(type) { return function (element, node, option, property, value, idx) { var label = idx + ' : '; var variableMappings = getVariableMappings(element, type); var mappingValue = variableMappings[idx]; var mappingType = getInOutType(mappingValue); if (mappingType === 'variables') { label = label + 'all'; } else if (mappingType === 'source') { label = label + (mappingValue.source || ''); } else if (mappingType === 'sourceExpression') { label = label + (mappingValue.sourceExpression || ''); } else { label = label + ''; } option.text = label; }; }; var newElement = function newElement(type) { return function (element, extensionElements, value) { var newElem = elementHelper.createElement(type, { source: '' }, extensionElements, bpmnFactory); return cmdHelper.addElementsTolist(element, extensionElements, 'values', [newElem]); }; }; var removeElement = function removeElement(type) { return function (element, extensionElements, value, idx) { var variablesMappings = getVariableMappings(element, type); var mapping = variablesMappings[idx]; if (mapping) { return extensionElementsHelper.removeEntry(getBusinessObject(element), element, mapping); } }; }; // in mapping for source and sourceExpression /////////////////////////////////////////////////////////////// var inEntry = extensionElementsEntry(element, bpmnFactory, { id: 'variableMapping-in', label: translate('In Mapping'), modelProperty: 'source', prefix: 'In', idGeneration: false, resizable: true, createExtensionElement: newElement(CAMUNDA_IN_EXTENSION_ELEMENT), removeExtensionElement: removeElement(CAMUNDA_IN_EXTENSION_ELEMENT), getExtensionElements: function getExtensionElements(element) { return getVariableMappings(element, CAMUNDA_IN_EXTENSION_ELEMENT); }, onSelectionChange: function onSelectionChange(element, node, event, scope) { outEntry && outEntry.deselect(element, node.parentNode); }, setOptionLabelValue: setOptionLabelValue(CAMUNDA_IN_EXTENSION_ELEMENT) }); group.entries.push(inEntry); // out mapping for source and sourceExpression /////////////////////////////////////////////////////// var outEntry = extensionElementsEntry(element, bpmnFactory, { id: 'variableMapping-out', label: translate('Out Mapping'), modelProperty: 'source', prefix: 'Out', idGeneration: false, resizable: true, createExtensionElement: newElement(CAMUNDA_OUT_EXTENSION_ELEMENT), removeExtensionElement: removeElement(CAMUNDA_OUT_EXTENSION_ELEMENT), getExtensionElements: function getExtensionElements(element) { return getVariableMappings(element, CAMUNDA_OUT_EXTENSION_ELEMENT); }, onSelectionChange: function onSelectionChange(element, node, event, scope) { inEntry.deselect(element, node.parentNode); }, setOptionLabelValue: setOptionLabelValue(CAMUNDA_OUT_EXTENSION_ELEMENT) }); group.entries.push(outEntry); // label for selected mapping /////////////////////////////////////////////////////// group.entries.push(entryFactory.label({ id: 'variableMapping-typeLabel', get: function get(element, node) { var mapping = getSelected(element, node); var value = ''; if (is(mapping, CAMUNDA_IN_EXTENSION_ELEMENT)) { value = translate('In Mapping'); } else if (is(mapping, CAMUNDA_OUT_EXTENSION_ELEMENT)) { value = translate('Out Mapping'); } return { label: value }; }, showLabel: function showLabel(element, node) { return isSelected(element, node); } })); group.entries.push(entryFactory.selectBox({ id: 'variableMapping-inOutType', label: translate('Type'), selectOptions: inOutTypeOptions, modelProperty: 'inOutType', get: function get(element, node) { var mapping = getSelected(element, node) || {}; return { inOutType: getInOutType(mapping) }; }, set: function set(element, values, node) { var inOutType = values.inOutType; var props = { 'source': undefined, 'sourceExpression': undefined, 'variables': undefined }; if (inOutType === 'source') { props.source = ''; } else if (inOutType === 'sourceExpression') { props.sourceExpression = ''; } else if (inOutType === 'variables') { props.variables = 'all'; } var mapping = getSelected(element, node); return cmdHelper.updateBusinessObject(element, mapping, props); }, hidden: function hidden(element, node) { return !isSelected(element, node); } })); group.entries.push(entryFactory.textField({ id: 'variableMapping-source', dataValueLabel: 'sourceLabel', modelProperty: 'source', get: function get(element, node) { var mapping = getSelected(element, node) || {}; var label = ''; var inOutType = getInOutType(mapping); if (inOutType === 'source') { label = 'Source'; } else if (inOutType === 'sourceExpression') { label = 'Source Expression'; } return { source: mapping[inOutType], sourceLabel: label }; }, set: function set(element, values, node) { values.source = values.source || undefined; var mapping = getSelected(element, node); var inOutType = getInOutType(mapping); var props = {}; props[inOutType] = values.source || ''; return cmdHelper.updateBusinessObject(element, mapping, props); }, // one of both (source or sourceExpression) must have a value to make // the configuration easier and more understandable // it is not engine conform validate: function validate(element, values, node) { var mapping = getSelected(element, node); var validation = {}; if (mapping) { if (!values.source) { validation.source = 'Mapping must have a ' + values.sourceLabel.toLowerCase() || 'value'; } } return validation; }, hidden: function hidden(element, node) { var selectedMapping = getSelected(element, node); return !selectedMapping || selectedMapping && selectedMapping.variables; } })); group.entries.push(entryFactory.textField({ id: 'variableMapping-target', label: translate('Target'), modelProperty: 'target', get: function get(element, node) { return { target: (getSelected(element, node) || {}).target }; }, set: function set(element, values, node) { values.target = values.target || undefined; var mapping = getSelected(element, node); return cmdHelper.updateBusinessObject(element, mapping, values); }, validate: function validate(element, values, node) { var mapping = getSelected(element, node); var validation = {}; if (mapping) { var mappingType = getInOutType(mapping); if (!values.target && mappingType !== 'variables') { validation.target = 'Mapping must have a target'; } } return validation; }, hidden: function hidden(element, node) { var selectedMapping = getSelected(element, node); return !selectedMapping || selectedMapping && selectedMapping.variables; } })); group.entries.push(entryFactory.checkbox({ id: 'variableMapping-local', label: translate('Local'), modelProperty: 'local', get: function get(element, node) { return { local: (getSelected(element, node) || {}).local }; }, set: function set(element, values, node) { values.local = values.local || false; var mapping = getSelected(element, node); return cmdHelper.updateBusinessObject(element, mapping, values); }, hidden: function hidden(element, node) { return !isSelected(element, node); } })); }; },{"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"../../../helper/ElementHelper":25,"../../../helper/ExtensionElementsHelper":27,"./implementation/ExtensionElements":90,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/filter":420}],86:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../factory/EntryFactory'), cmdHelper = require('../../../helper/CmdHelper'), is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; module.exports = function (group, element, translate) { var bo = getBusinessObject(element); if (!bo) { return; } if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && bo.get('processRef')) { var versionTagEntry = entryFactory.textField({ id: 'versionTag', label: translate('Version Tag'), modelProperty: 'versionTag' }); // in participants we have to change the default behavior of set and get if (is(element, 'bpmn:Participant')) { versionTagEntry.get = function (element) { var processBo = bo.get('processRef'); return { versionTag: processBo.get('camunda:versionTag') }; }; versionTagEntry.set = function (element, values) { var processBo = bo.get('processRef'); return cmdHelper.updateBusinessObject(element, processBo, { 'camunda:versionTag': values.versionTag || undefined }); }; } group.entries.push(versionTagEntry); } }; },{"../../../factory/EntryFactory":14,"../../../helper/CmdHelper":24,"bpmn-js/lib/util/ModelUtil":216}],87:[function(require,module,exports){ 'use strict'; var assign = require('lodash/object/assign'); var entryFactory = require('../../../../factory/EntryFactory'); var asyncCapableHelper = require('../../../../helper/AsyncCapableHelper'), eventDefinitionHelper = require('../../../../helper/EventDefinitionHelper'), cmdHelper = require('../../../../helper/CmdHelper'); function isAsyncBefore(bo) { return asyncCapableHelper.isAsyncBefore(bo); } function isAsyncAfter(bo) { return asyncCapableHelper.isAsyncAfter(bo); } function isExclusive(bo) { return asyncCapableHelper.isExclusive(bo); } function removeFailedJobRetryTimeCycle(bo, element) { return asyncCapableHelper.removeFailedJobRetryTimeCycle(bo, element); } function canRemoveFailedJobRetryTimeCycle(element) { return !eventDefinitionHelper.getTimerEventDefinition(element); } module.exports = function (element, bpmnFactory, options, translate) { var getBusinessObject = options.getBusinessObject; var idPrefix = options.idPrefix || '', labelPrefix = options.labelPrefix || ''; var asyncBeforeEntry = entryFactory.checkbox({ id: idPrefix + 'asyncBefore', label: labelPrefix + translate('Asynchronous Before'), modelProperty: 'asyncBefore', get: function get(element, node) { var bo = getBusinessObject(element); return { asyncBefore: isAsyncBefore(bo) }; }, set: function set(element, values) { var bo = getBusinessObject(element); var asyncBefore = !!values.asyncBefore; var props = { 'camunda:asyncBefore': asyncBefore, 'camunda:async': false }; var commands = []; if (!isAsyncAfter(bo) && !asyncBefore) { props = assign({ 'camunda:exclusive': true }, props); if (canRemoveFailedJobRetryTimeCycle(element)) { commands.push(removeFailedJobRetryTimeCycle(bo, element)); } } commands.push(cmdHelper.updateBusinessObject(element, bo, props)); return commands; } }); var asyncAfterEntry = entryFactory.checkbox({ id: idPrefix + 'asyncAfter', label: labelPrefix + translate('Asynchronous After'), modelProperty: 'asyncAfter', get: function get(element, node) { var bo = getBusinessObject(element); return { asyncAfter: isAsyncAfter(bo) }; }, set: function set(element, values) { var bo = getBusinessObject(element); var asyncAfter = !!values.asyncAfter; var props = { 'camunda:asyncAfter': asyncAfter }; var commands = []; if (!isAsyncBefore(bo) && !asyncAfter) { props = assign({ 'camunda:exclusive': true }, props); if (canRemoveFailedJobRetryTimeCycle(element)) { commands.push(removeFailedJobRetryTimeCycle(bo, element)); } } commands.push(cmdHelper.updateBusinessObject(element, bo, props)); return commands; } }); var exclusiveEntry = entryFactory.checkbox({ id: idPrefix + 'exclusive', label: labelPrefix + translate('Exclusive'), modelProperty: 'exclusive', get: function get(element, node) { var bo = getBusinessObject(element); return { exclusive: isExclusive(bo) }; }, set: function set(element, values) { var bo = getBusinessObject(element); return cmdHelper.updateBusinessObject(element, bo, { 'camunda:exclusive': !!values.exclusive }); }, hidden: function hidden(element) { var bo = getBusinessObject(element); return bo && !isAsyncAfter(bo) && !isAsyncBefore(bo); } }); return [asyncBeforeEntry, asyncAfterEntry, exclusiveEntry]; }; },{"../../../../factory/EntryFactory":14,"../../../../helper/AsyncCapableHelper":23,"../../../../helper/CmdHelper":24,"../../../../helper/EventDefinitionHelper":26,"lodash/object/assign":496}],88:[function(require,module,exports){ 'use strict'; var cmdHelper = require('../../../../helper/CmdHelper'), entryFactory = require('../../../../factory/EntryFactory'), elementHelper = require('../../../../helper/ElementHelper'), extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'); var resultVariable = require('./ResultVariable'); var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var is = require('bpmn-js/lib/util/ModelUtil').is; var forEach = require('lodash/collection/forEach'); var attributeInfo = { bpmn: { element: 'calledElement', binding: 'camunda:calledElementBinding', version: 'camunda:calledElementVersion', tenantId: 'camunda:calledElementTenantId' }, cmmn: { element: 'camunda:caseRef', binding: 'camunda:caseBinding', version: 'camunda:caseVersion', tenantId: 'camunda:caseTenantId' }, dmn: { element: 'camunda:decisionRef', binding: 'camunda:decisionRefBinding', version: 'camunda:decisionRefVersion', tenantId: 'camunda:decisionRefTenantId' } }; var bindingOptions = [{ name: 'latest', value: 'latest' }, { name: 'deployment', value: 'deployment' }, { name: 'version', value: 'version' }]; var mapDecisionResultOptions = [{ name: 'singleEntry', value: 'singleEntry' }, { name: 'singleResult', value: 'singleResult' }, { name: 'collectEntries', value: 'collectEntries' }, { name: 'resultList', value: 'resultList' }]; var delegateVariableMappingOptions = [{ name: 'variableMappingClass', value: 'variableMappingClass' }, { name: 'variableMappingDelegateExpression', value: 'variableMappingDelegateExpression' }]; function getCamundaInWithBusinessKey(element) { var camundaIn = [], bo = getBusinessObject(element); var camundaInParams = extensionElementsHelper.getExtensionElements(bo, 'camunda:In'); if (camundaInParams) { forEach(camundaInParams, function (param) { if (param.businessKey) { camundaIn.push(param); } }); } return camundaIn; } function setBusinessKey(element, bpmnFactory) { var bo = getBusinessObject(element); var commands = []; var extensionElements = bo.extensionElements; if (!extensionElements) { extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory); commands.push(cmdHelper.updateProperties(element, { extensionElements: extensionElements })); } var camundaIn = elementHelper.createElement('camunda:In', { 'businessKey': '#{execution.processBusinessKey}' }, extensionElements, bpmnFactory); commands.push(cmdHelper.addAndRemoveElementsFromList(element, extensionElements, 'values', 'extensionElements', [camundaIn], [])); return commands; } function deleteBusinessKey(element) { var camundaInExtensions = getCamundaInWithBusinessKey(element); var commands = []; forEach(camundaInExtensions, function (elem) { commands.push(extensionElementsHelper.removeEntry(getBusinessObject(element), element, elem)); }); return commands; } function isSupportedCallableType(type) { return ['bpmn', 'cmmn', 'dmn'].indexOf(type) !== -1; } module.exports = function (element, bpmnFactory, options, translate) { var getCallableType = options.getCallableType; var entries = []; function getAttribute(element, prop) { var type = getCallableType(element); return (attributeInfo[type] || {})[prop]; } function getCallActivityBindingValue(element) { var type = getCallableType(element); var bo = getBusinessObject(element); var attr = (attributeInfo[type] || {}).binding; return bo.get(attr); } function getDelegateVariableMappingType(element) { var bo = getBusinessObject(element); var boVariableMappingClass = bo.get('camunda:variableMappingClass'), boVariableMappingDelegateExpression = bo.get('camunda:variableMappingDelegateExpression'); var delegateVariableMappingType = ''; if (typeof boVariableMappingClass !== 'undefined') { delegateVariableMappingType = 'variableMappingClass'; } else if (typeof boVariableMappingDelegateExpression !== 'undefined') { delegateVariableMappingType = 'variableMappingDelegateExpression'; } return delegateVariableMappingType; } entries.push(entryFactory.textField({ id: 'callable-element-ref', dataValueLabel: 'callableElementLabel', modelProperty: 'callableElementRef', get: function get(element, node) { var callableElementRef; var attr = getAttribute(element, 'element'); if (attr) { var bo = getBusinessObject(element); callableElementRef = bo.get(attr); } var label = ''; var type = getCallableType(element); if (type === 'bpmn') { label = translate('Called Element'); } else if (type === 'cmmn') { label = translate('Case Ref'); } else if (type === 'dmn') { label = translate('Decision Ref'); } return { callableElementRef: callableElementRef, callableElementLabel: label }; }, set: function set(element, values, node) { var newCallableElementRef = values.callableElementRef; var attr = getAttribute(element, 'element'); var props = {}; props[attr] = newCallableElementRef || ''; return cmdHelper.updateProperties(element, props); }, validate: function validate(element, values, node) { var elementRef = values.callableElementRef; var type = getCallableType(element); return isSupportedCallableType(type) && !elementRef ? { callableElementRef: 'Value must provide a value.' } : {}; }, hidden: function hidden(element, node) { return !isSupportedCallableType(getCallableType(element)); } })); entries.push(entryFactory.selectBox({ id: 'callable-binding', label: translate('Binding'), selectOptions: bindingOptions, modelProperty: 'callableBinding', get: function get(element, node) { var callableBinding; var attr = getAttribute(element, 'binding'); if (attr) { var bo = getBusinessObject(element); callableBinding = bo.get(attr) || 'latest'; } return { callableBinding: callableBinding }; }, set: function set(element, values, node) { var binding = values.callableBinding; var attr = getAttribute(element, 'binding'), attrVer = getAttribute(element, 'version'); var props = {}; props[attr] = binding; // set version value always on undefined to delete the existing value props[attrVer] = undefined; return cmdHelper.updateProperties(element, props); }, hidden: function hidden(element, node) { return !isSupportedCallableType(getCallableType(element)); } })); entries.push(entryFactory.textField({ id: 'callable-version', label: translate('Version'), modelProperty: 'callableVersion', get: function get(element, node) { var callableVersion; var attr = getAttribute(element, 'version'); if (attr) { var bo = getBusinessObject(element); callableVersion = bo.get(attr); } return { callableVersion: callableVersion }; }, set: function set(element, values, node) { var version = values.callableVersion; var attr = getAttribute(element, 'version'); var props = {}; props[attr] = version || undefined; return cmdHelper.updateProperties(element, props); }, validate: function validate(element, values, node) { var version = values.callableVersion; var type = getCallableType(element); return isSupportedCallableType(type) && getCallActivityBindingValue(element) === 'version' && !version ? { callableVersion: translate('Value must provide a value.') } : {}; }, hidden: function hidden(element, node) { var type = getCallableType(element); return !isSupportedCallableType(type) || getCallActivityBindingValue(element) !== 'version'; } })); entries.push(entryFactory.textField({ id: 'tenant-id', label: translate('Tenant Id'), modelProperty: 'tenantId', get: function get(element, node) { var tenantId; var attr = getAttribute(element, 'tenantId'); if (attr) { var bo = getBusinessObject(element); tenantId = bo.get(attr); } return { tenantId: tenantId }; }, set: function set(element, values, node) { var tenantId = values.tenantId; var attr = getAttribute(element, 'tenantId'); var props = {}; props[attr] = tenantId || undefined; return cmdHelper.updateProperties(element, props); }, hidden: function hidden(element, node) { var type = getCallableType(element); return !isSupportedCallableType(type); } })); if (is(getBusinessObject(element), 'bpmn:CallActivity')) { entries.push(entryFactory.checkbox({ id: 'callable-business-key', label: translate('Business Key'), modelProperty: 'callableBusinessKey', get: function get(element, node) { var camundaIn = getCamundaInWithBusinessKey(element); return { callableBusinessKey: !!(camundaIn && camundaIn.length > 0) }; }, set: function set(element, values, node) { if (values.callableBusinessKey) { return setBusinessKey(element, bpmnFactory); } else { return deleteBusinessKey(element); } } })); } entries = entries.concat(resultVariable(element, bpmnFactory, { id: 'dmn-resultVariable', getBusinessObject: getBusinessObject, getImplementationType: getCallableType, hideResultVariable: function hideResultVariable(element, node) { return getCallableType(element) !== 'dmn'; } }, translate)); entries.push(entryFactory.selectBox({ id: 'dmn-map-decision-result', label: translate('Map Decision Result'), selectOptions: mapDecisionResultOptions, modelProperty: 'mapDecisionResult', get: function get(element, node) { var bo = getBusinessObject(element); return { mapDecisionResult: bo.get('camunda:mapDecisionResult') || 'resultList' }; }, set: function set(element, values, node) { return cmdHelper.updateProperties(element, { 'camunda:mapDecisionResult': values.mapDecisionResult || 'resultList' }); }, hidden: function hidden(element, node) { var bo = getBusinessObject(element); var resultVariable = bo.get('camunda:resultVariable'); return !(getCallableType(element) === 'dmn' && typeof resultVariable !== 'undefined'); } })); entries.push(entryFactory.selectBox({ id: 'delegateVariableMappingType', label: translate('Delegate Variable Mapping'), selectOptions: delegateVariableMappingOptions, emptyParameter: true, modelProperty: 'delegateVariableMappingType', get: function get(element, node) { return { delegateVariableMappingType: getDelegateVariableMappingType(element) }; }, set: function set(element, values, node) { var delegateVariableMappingType = values.delegateVariableMappingType; var props = { 'camunda:variableMappingClass': undefined, 'camunda:variableMappingDelegateExpression': undefined }; if (delegateVariableMappingType === 'variableMappingClass') { props['camunda:variableMappingClass'] = ''; } else if (delegateVariableMappingType === 'variableMappingDelegateExpression') { props['camunda:variableMappingDelegateExpression'] = ''; } return cmdHelper.updateProperties(element, props); }, hidden: function hidden(element, node) { return getCallableType(element) !== 'bpmn'; } })); entries.push(entryFactory.textField({ id: 'delegateVariableMapping', dataValueLabel: 'delegateVariableMappingLabel', modelProperty: 'delegateVariableMapping', get: function get(element, node) { var bo = getBusinessObject(element); var label = ''; var delegateVariableMapping = undefined; var type = getDelegateVariableMappingType(element); if (type === 'variableMappingClass') { label = translate('Class'); delegateVariableMapping = bo.get('camunda:variableMappingClass'); } else if (type === 'variableMappingDelegateExpression') { label = translate('Delegate Expression'); delegateVariableMapping = bo.get('camunda:variableMappingDelegateExpression'); } return { delegateVariableMapping: delegateVariableMapping, delegateVariableMappingLabel: label }; }, set: function set(element, values, node) { var delegateVariableMapping = values.delegateVariableMapping; var attr = 'camunda:' + getDelegateVariableMappingType(element); var props = {}; props[attr] = delegateVariableMapping || undefined; return cmdHelper.updateProperties(element, props); }, validate: function validate(element, values, node) { var delegateVariableMapping = values.delegateVariableMapping; return getCallableType(element) === 'bpmn' && !delegateVariableMapping ? { delegateVariableMapping: translate('Must provide a value.') } : {}; }, hidden: function hidden(element, node) { return !(getCallableType(element) === 'bpmn' && getDelegateVariableMappingType(element) !== ''); } })); return entries; }; },{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../../../../helper/ExtensionElementsHelper":27,"./ResultVariable":103,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/forEach":422}],89:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'), cmdHelper = require('../../../../helper/CmdHelper'); var DELEGATE_TYPES = ['class', 'expression', 'delegateExpression']; var PROPERTIES = { class: 'camunda:class', expression: 'camunda:expression', delegateExpression: 'camunda:delegateExpression' }; function isDelegate(type) { return DELEGATE_TYPES.indexOf(type) !== -1; } function getAttribute(type) { return PROPERTIES[type]; } module.exports = function (element, bpmnFactory, options, translate) { var getImplementationType = options.getImplementationType, getBusinessObject = options.getBusinessObject; function getDelegationLabel(type) { switch (type) { case 'class': return translate('Java Class'); case 'expression': return translate('Expression'); case 'delegateExpression': return translate('Delegate Expression'); default: return ''; } } var delegateEntry = entryFactory.textField({ id: 'delegate', label: translate('Value'), dataValueLabel: 'delegationLabel', modelProperty: 'delegate', get: function get(element, node) { var bo = getBusinessObject(element); var type = getImplementationType(element); var attr = getAttribute(type); var label = getDelegationLabel(type); return { delegate: bo.get(attr), delegationLabel: label }; }, set: function set(element, values, node) { var bo = getBusinessObject(element); var type = getImplementationType(element); var attr = getAttribute(type); var prop = {}; prop[attr] = values.delegate || ''; return cmdHelper.updateBusinessObject(element, bo, prop); }, validate: function validate(element, values, node) { return isDelegate(getImplementationType(element)) && !values.delegate ? { delegate: 'Must provide a value' } : {}; }, hidden: function hidden(element, node) { return !isDelegate(getImplementationType(element)); } }); return [delegateEntry]; }; },{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24}],90:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var domQuery = require('min-dom/lib/query'), domClosest = require('min-dom/lib/closest'), domify = require('min-dom/lib/domify'), forEach = require('lodash/collection/forEach'); var elementHelper = require('../../../../helper/ElementHelper'), cmdHelper = require('../../../../helper/CmdHelper'), utils = require('../../../../Utils'); function getSelectBox(node, id) { var currentTab = domClosest(node, 'div.bpp-properties-tab'); var query = 'select[name=selectedExtensionElement]' + (id ? '[id=cam-extensionElements-' + id + ']' : ''); return domQuery(query, currentTab); } function _getSelected(node, id) { var selectBox = getSelectBox(node, id); return { value: (selectBox || {}).value, idx: (selectBox || {}).selectedIndex }; } function generateElementId(prefix) { prefix = prefix + '_'; return utils.nextId(prefix); } var CREATE_EXTENSION_ELEMENT_ACTION = 'create-extension-element', REMOVE_EXTENSION_ELEMENT_ACTION = 'remove-extension-element'; module.exports = function (element, bpmnFactory, options, translate) { var id = options.id, prefix = options.prefix || 'elem', label = options.label || id, idGeneration = options.idGeneration === false ? options.idGeneration : true, businessObject = options.businessObject || getBusinessObject(element); var modelProperty = options.modelProperty || 'id'; var getElements = options.getExtensionElements; var createElement = options.createExtensionElement, canCreate = typeof createElement === 'function'; var removeElement = options.removeExtensionElement, canRemove = typeof removeElement === 'function'; var onSelectionChange = options.onSelectionChange; var _hideElements = options.hideExtensionElements, canBeHidden = typeof _hideElements === 'function'; var setOptionLabelValue = options.setOptionLabelValue; var defaultSize = options.size || 5, resizable = options.resizable; var reference = options.reference || undefined; var selectionChanged = function selectionChanged(element, node, event, scope) { if (typeof onSelectionChange === 'function') { return onSelectionChange(element, node, event, scope); } }; var createOption = function createOption(value) { return ''; }; var initSelectionSize = function initSelectionSize(selectBox, optionsLength) { if (resizable) { selectBox.size = optionsLength > defaultSize ? optionsLength : defaultSize; } }; return { id: id, html: '
' + '' + '
' + '' + (canCreate ? '' : '') + (canRemove ? '' : '') + '
' + '
', get: function get(element, node) { var elements = getElements(element, node); var result = []; forEach(elements, function (elem) { result.push({ extensionElementValue: elem.get(modelProperty) }); }); var selectBox = getSelectBox(node.parentNode, id); initSelectionSize(selectBox, result.length); return result; }, set: function set(element, values, node) { var action = this.__action; delete this.__action; businessObject = businessObject || getBusinessObject(element); var bo = reference && businessObject.get(reference) ? businessObject.get(reference) : businessObject; var extensionElements = bo.get('extensionElements'); if (action.id === CREATE_EXTENSION_ELEMENT_ACTION) { var commands = []; if (!extensionElements) { extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory); commands.push(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements })); } commands.push(createElement(element, extensionElements, action.value, node)); return commands; } else if (action.id === REMOVE_EXTENSION_ELEMENT_ACTION) { return removeElement(element, extensionElements, action.value, action.idx, node); } }, createListEntryTemplate: function createListEntryTemplate(value, index, selectBox) { initSelectionSize(selectBox, selectBox.options.length + 1); return createOption(value.extensionElementValue); }, deselect: function deselect(element, node) { var selectBox = getSelectBox(node, id); selectBox.selectedIndex = -1; }, getSelected: function getSelected(element, node) { return _getSelected(node, id); }, setControlValue: function setControlValue(element, node, option, property, value, idx) { node.value = value; if (!setOptionLabelValue) { node.text = value; } else { setOptionLabelValue(element, node, option, property, value, idx); } }, createElement: function createElement(element, node) { // create option template var generatedId; if (idGeneration) { generatedId = generateElementId(prefix); } var selectBox = getSelectBox(node, id); var template = domify(createOption(generatedId)); // add new empty option as last child element selectBox.appendChild(template); // select last child element selectBox.lastChild.selected = 'selected'; selectionChanged(element, node); // update select box size initSelectionSize(selectBox, selectBox.options.length); this.__action = { id: CREATE_EXTENSION_ELEMENT_ACTION, value: generatedId }; return true; }, removeElement: function removeElement(element, node) { var selection = _getSelected(node, id); var selectBox = getSelectBox(node, id); selectBox.removeChild(selectBox.options[selection.idx]); // update select box size initSelectionSize(selectBox, selectBox.options.length); this.__action = { id: REMOVE_EXTENSION_ELEMENT_ACTION, value: selection.value, idx: selection.idx }; return true; }, hideElements: function hideElements(element, entryNode, node, scopeNode) { return !_hideElements(element, entryNode, node, scopeNode); }, disableRemove: function disableRemove(element, entryNode, node, scopeNode) { return (_getSelected(entryNode, id) || {}).idx < 0; }, selectElement: selectionChanged }; }; },{"../../../../Utils":5,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/forEach":422,"min-dom/lib/closest":108,"min-dom/lib/domify":110,"min-dom/lib/query":112}],91:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'), cmdHelper = require('../../../../helper/CmdHelper'); module.exports = function (element, bpmnFactory, options, translate) { var getImplementationType = options.getImplementationType, getBusinessObject = options.getBusinessObject; function isExternal(element) { return getImplementationType(element) === 'external'; } var topicEntry = entryFactory.textField({ id: 'externalTopic', label: translate('Topic'), modelProperty: 'externalTopic', get: function get(element, node) { var bo = getBusinessObject(element); return { externalTopic: bo.get('camunda:topic') }; }, set: function set(element, values, node) { var bo = getBusinessObject(element); return cmdHelper.updateBusinessObject(element, bo, { 'camunda:topic': values.externalTopic }); }, validate: function validate(element, values, node) { return isExternal(element) && !values.externalTopic ? { externalTopic: 'Must provide a value' } : {}; }, hidden: function hidden(element, node) { return !isExternal(element); } }); return [topicEntry]; }; },{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24}],92:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'); var cmdHelper = require('../../../../helper/CmdHelper'); module.exports = function (element, bpmnFactory, options, translate) { var getBusinessObject = options.getBusinessObject; var externalTaskPriorityEntry = entryFactory.textField({ id: 'externalTaskPriority', label: translate('Task Priority'), modelProperty: 'taskPriority', get: function get(element, node) { var bo = getBusinessObject(element); return { taskPriority: bo.get('camunda:taskPriority') }; }, set: function set(element, values) { var bo = getBusinessObject(element); return cmdHelper.updateBusinessObject(element, bo, { 'camunda:taskPriority': values.taskPriority || undefined }); } }); return [externalTaskPriorityEntry]; }; },{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24}],93:[function(require,module,exports){ 'use strict'; var extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'), elementHelper = require('../../../../helper/ElementHelper'), cmdHelper = require('../../../../helper/CmdHelper'); var utils = require('../../../../Utils'); var entryFactory = require('../../../../factory/EntryFactory'); var extensionElementsEntry = require('./ExtensionElements'); var ModelUtil = require('bpmn-js/lib/util/ModelUtil'), getBusinessObject = ModelUtil.getBusinessObject; var assign = require('lodash/object/assign'); var DEFAULT_PROPS = { 'stringValue': undefined, 'string': undefined, 'expression': undefined }; var CAMUNDA_FIELD_EXTENSION_ELEMENT = 'camunda:Field'; module.exports = function (element, bpmnFactory, translate, options) { options = options || {}; var insideListener = !!options.insideListener, idPrefix = options.idPrefix || '', getSelectedListener = options.getSelectedListener, businessObject = options.businessObject || getBusinessObject(element); var entries = []; var isSelected = function isSelected(element, node) { return getSelectedField(element, node); }; function getSelectedField(element, node) { var selected = fieldEntry.getSelected(element, node.parentNode); if (selected.idx === -1) { return; } var fields = getCamundaFields(element, node); return fields[selected.idx]; } function getCamundaFields(element, node) { if (!insideListener) { return businessObject && extensionElementsHelper.getExtensionElements(businessObject, CAMUNDA_FIELD_EXTENSION_ELEMENT) || []; } return getCamundaListenerFields(element, node); } function getCamundaListenerFields(element, node) { var selectedListener = getSelectedListener(element, node); return selectedListener && selectedListener.fields || []; } function getFieldType(bo) { var fieldType = 'string'; var expressionValue = bo && bo.expression; var stringValue = bo && (bo.string || bo.stringValue); if (typeof stringValue !== 'undefined') { fieldType = 'string'; } else if (typeof expressionValue !== 'undefined') { fieldType = 'expression'; } return fieldType; } var setOptionLabelValue = function setOptionLabelValue() { return function (element, node, option, property, value, idx) { var camundaFields = getCamundaFields(element, node); var field = camundaFields[idx]; value = field.name ? field.name : ''; var label = idx + ' : ' + value; option.text = label; }; }; var newElement = function newElement() { return function (element, extensionElements, value, node) { var props = { name: '', string: '' }; var newFieldElem; if (!insideListener) { newFieldElem = elementHelper.createElement(CAMUNDA_FIELD_EXTENSION_ELEMENT, props, extensionElements, bpmnFactory); return cmdHelper.addElementsTolist(element, extensionElements, 'values', [newFieldElem]); } else { var selectedListener = getSelectedListener(element, node); newFieldElem = elementHelper.createElement(CAMUNDA_FIELD_EXTENSION_ELEMENT, props, selectedListener, bpmnFactory); return cmdHelper.addElementsTolist(element, selectedListener, 'fields', [newFieldElem]); } }; }; var removeElement = function removeElement() { return function (element, extensionElements, value, idx, node) { var camundaFields = getCamundaFields(element, node); var field = camundaFields[idx]; if (field) { if (!insideListener) { return extensionElementsHelper.removeEntry(businessObject, element, field); } var selectedListener = getSelectedListener(element, node); return cmdHelper.removeElementsFromList(element, selectedListener, 'fields', null, [field]); } }; }; var fieldEntry = extensionElementsEntry(element, bpmnFactory, { id: idPrefix + 'fields', label: translate('Fields'), modelProperty: 'fieldName', idGeneration: 'false', businessObject: businessObject, createExtensionElement: newElement(), removeExtensionElement: removeElement(), getExtensionElements: function getExtensionElements(element, node) { return getCamundaFields(element, node); }, setOptionLabelValue: setOptionLabelValue() }); entries.push(fieldEntry); entries.push(entryFactory.validationAwareTextField({ id: idPrefix + 'field-name', label: translate('Name'), modelProperty: 'fieldName', getProperty: function getProperty(element, node) { return (getSelectedField(element, node) || {}).name; }, setProperty: function setProperty(element, values, node) { var selectedField = getSelectedField(element, node); return cmdHelper.updateBusinessObject(element, selectedField, { name: values.fieldName }); }, validate: function validate(element, values, node) { var bo = getSelectedField(element, node); var validation = {}; if (bo) { var nameValue = values.fieldName; if (nameValue) { if (utils.containsSpace(nameValue)) { validation.fieldName = translate('Name must not contain spaces'); } } else { validation.fieldName = translate('Parameter must have a name'); } } return validation; }, hidden: function hidden(element, node) { return !isSelected(element, node); } })); var fieldTypeOptions = [{ name: translate('String'), value: 'string' }, { name: translate('Expression'), value: 'expression' }]; entries.push(entryFactory.selectBox({ id: idPrefix + 'field-type', label: translate('Type'), selectOptions: fieldTypeOptions, modelProperty: 'fieldType', get: function get(element, node) { var bo = getSelectedField(element, node); var fieldType = getFieldType(bo); return { fieldType: fieldType }; }, set: function set(element, values, node) { var props = assign({}, DEFAULT_PROPS); var fieldType = values.fieldType; if (fieldType === 'string') { props.string = ''; } else if (fieldType === 'expression') { props.expression = ''; } return cmdHelper.updateBusinessObject(element, getSelectedField(element, node), props); }, hidden: function hidden(element, node) { return !isSelected(element, node); } })); entries.push(entryFactory.textBox({ id: idPrefix + 'field-value', label: translate('Value'), modelProperty: 'fieldValue', get: function get(element, node) { var bo = getSelectedField(element, node); var fieldType = getFieldType(bo); var fieldValue; if (fieldType === 'string') { fieldValue = bo && (bo.string || bo.stringValue); } else if (fieldType === 'expression') { fieldValue = bo && bo.expression; } return { fieldValue: fieldValue }; }, set: function set(element, values, node) { var bo = getSelectedField(element, node); var fieldType = getFieldType(bo); var props = assign({}, DEFAULT_PROPS); var fieldValue = values.fieldValue || undefined; if (fieldType === 'string') { props.string = fieldValue; } else if (fieldType === 'expression') { props.expression = fieldValue; } return cmdHelper.updateBusinessObject(element, bo, props); }, validate: function validate(element, values, node) { var bo = getSelectedField(element, node); var validation = {}; if (bo) { if (!values.fieldValue) { validation.fieldValue = translate('Must provide a value'); } } return validation; }, show: function show(element, node) { return isSelected(element, node); } })); return entries; }; },{"../../../../Utils":5,"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../../../../helper/ExtensionElementsHelper":27,"./ExtensionElements":90,"bpmn-js/lib/util/ModelUtil":216,"lodash/object/assign":496}],94:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'); var cmdHelper = require('../../../../helper/CmdHelper'); module.exports = function (element, bpmnFactory, options, translate) { var getBusinessObject = options.getBusinessObject; var historyTimeToLiveEntry = entryFactory.textField({ id: 'historyTimeToLive', label: translate('History Time To Live'), modelProperty: 'historyTimeToLive', get: function get(element, node) { var bo = getBusinessObject(element); var historyTimeToLive = bo.get('camunda:historyTimeToLive'); return { historyTimeToLive: historyTimeToLive ? historyTimeToLive : '' }; }, set: function set(element, values) { var bo = getBusinessObject(element); return cmdHelper.updateBusinessObject(element, bo, { 'camunda:historyTimeToLive': values.historyTimeToLive || undefined }); } }); return [historyTimeToLiveEntry]; }; },{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24}],95:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'), cmdHelper = require('../../../../helper/CmdHelper'), extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'), elementHelper = require('../../../../helper/ElementHelper'); var assign = require('lodash/object/assign'); var map = require('lodash/collection/map'); var DEFAULT_DELEGATE_PROPS = ['class', 'expression', 'delegateExpression']; var DELEGATE_PROPS = { 'camunda:class': undefined, 'camunda:expression': undefined, 'camunda:delegateExpression': undefined, 'camunda:resultVariable': undefined }; var DMN_CAPABLE_PROPS = { 'camunda:decisionRef': undefined, 'camunda:decisionRefBinding': 'latest', 'camunda:decisionRefVersion': undefined, 'camunda:mapDecisionResult': 'resultList', 'camunda:decisionRefTenantId': undefined }; var EXTERNAL_CAPABLE_PROPS = { 'camunda:type': undefined, 'camunda:topic': undefined }; module.exports = function (element, bpmnFactory, options, translate) { var DEFAULT_OPTIONS = [{ value: 'class', name: translate('Java Class') }, { value: 'expression', name: translate('Expression') }, { value: 'delegateExpression', name: translate('Delegate Expression') }]; var DMN_OPTION = [{ value: 'dmn', name: translate('DMN') }]; var EXTERNAL_OPTION = [{ value: 'external', name: translate('External') }]; var CONNECTOR_OPTION = [{ value: 'connector', name: translate('Connector') }]; var SCRIPT_OPTION = [{ value: 'script', name: translate('Script') }]; var getType = options.getImplementationType, getBusinessObject = options.getBusinessObject; var hasDmnSupport = options.hasDmnSupport, hasExternalSupport = options.hasExternalSupport, hasServiceTaskLikeSupport = options.hasServiceTaskLikeSupport, hasScriptSupport = options.hasScriptSupport; var entries = []; var selectOptions = DEFAULT_OPTIONS.concat([]); if (hasDmnSupport) { selectOptions = selectOptions.concat(DMN_OPTION); } if (hasExternalSupport) { selectOptions = selectOptions.concat(EXTERNAL_OPTION); } if (hasServiceTaskLikeSupport) { selectOptions = selectOptions.concat(CONNECTOR_OPTION); } if (hasScriptSupport) { selectOptions = selectOptions.concat(SCRIPT_OPTION); } selectOptions.push({ value: '' }); entries.push(entryFactory.selectBox({ id: 'implementation', label: translate('Implementation'), selectOptions: selectOptions, modelProperty: 'implType', get: function get(element, node) { return { implType: getType(element) || '' }; }, set: function set(element, values, node) { var bo = getBusinessObject(element); var oldType = getType(element); var newType = values.implType; var props = assign({}, DELEGATE_PROPS); if (DEFAULT_DELEGATE_PROPS.indexOf(newType) !== -1) { var newValue = ''; if (DEFAULT_DELEGATE_PROPS.indexOf(oldType) !== -1) { newValue = bo.get('camunda:' + oldType); } props['camunda:' + newType] = newValue; } if (hasDmnSupport) { props = assign(props, DMN_CAPABLE_PROPS); if (newType === 'dmn') { props['camunda:decisionRef'] = ''; } } if (hasExternalSupport) { props = assign(props, EXTERNAL_CAPABLE_PROPS); if (newType === 'external') { props['camunda:type'] = 'external'; props['camunda:topic'] = ''; } } if (hasScriptSupport) { props['camunda:script'] = undefined; if (newType === 'script') { props['camunda:script'] = elementHelper.createElement('camunda:Script', {}, bo, bpmnFactory); } } var commands = []; commands.push(cmdHelper.updateBusinessObject(element, bo, props)); if (hasServiceTaskLikeSupport) { var connectors = extensionElementsHelper.getExtensionElements(bo, 'camunda:Connector'); commands.push(map(connectors, function (connector) { return extensionElementsHelper.removeEntry(bo, element, connector); })); if (newType === 'connector') { var extensionElements = bo.get('extensionElements'); if (!extensionElements) { extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory); commands.push(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements })); } var connector = elementHelper.createElement('camunda:Connector', {}, extensionElements, bpmnFactory); commands.push(cmdHelper.addAndRemoveElementsFromList(element, extensionElements, 'values', 'extensionElements', [connector], [])); } } return commands; } })); return entries; }; },{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../../../../helper/ExtensionElementsHelper":27,"lodash/collection/map":424,"lodash/object/assign":496}],96:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var elementHelper = require('../../../../helper/ElementHelper'), extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'), inputOutputHelper = require('../../../../helper/InputOutputHelper'), cmdHelper = require('../../../../helper/CmdHelper'); var extensionElementsEntry = require('./ExtensionElements'); function getInputOutput(element, insideConnector) { return inputOutputHelper.getInputOutput(element, insideConnector); } function getConnector(element) { return inputOutputHelper.getConnector(element); } function getInputParameters(element, insideConnector) { return inputOutputHelper.getInputParameters(element, insideConnector); } function getOutputParameters(element, insideConnector) { return inputOutputHelper.getOutputParameters(element, insideConnector); } function getInputParameter(element, insideConnector, idx) { return inputOutputHelper.getInputParameter(element, insideConnector, idx); } function getOutputParameter(element, insideConnector, idx) { return inputOutputHelper.getOutputParameter(element, insideConnector, idx); } function createElement(type, parent, factory, properties) { return elementHelper.createElement(type, properties, parent, factory); } function createInputOutput(parent, bpmnFactory, properties) { return createElement('camunda:InputOutput', parent, bpmnFactory, properties); } function createParameter(type, parent, bpmnFactory, properties) { return createElement(type, parent, bpmnFactory, properties); } function ensureInputOutputSupported(element, insideConnector) { return inputOutputHelper.isInputOutputSupported(element, insideConnector); } function ensureOutparameterSupported(element, insideConnector) { return inputOutputHelper.areOutputParametersSupported(element, insideConnector); } module.exports = function (element, bpmnFactory, options, translate) { var TYPE_LABEL = { 'camunda:Map': translate('Map'), 'camunda:List': translate('List'), 'camunda:Script': translate('Script') }; options = options || {}; var insideConnector = !!options.insideConnector, idPrefix = options.idPrefix || ''; var getSelected = function getSelected(element, node) { var selection = inputEntry && inputEntry.getSelected(element, node) || { idx: -1 }; var parameter = getInputParameter(element, insideConnector, selection.idx); if (!parameter && outputEntry) { selection = outputEntry.getSelected(element, node); parameter = getOutputParameter(element, insideConnector, selection.idx); } return parameter; }; var result = { getSelectedParameter: getSelected }; var entries = result.entries = []; if (!ensureInputOutputSupported(element)) { return result; } var newElement = function newElement(type, prop, factory) { return function (element, extensionElements, value) { var commands = []; var inputOutput = getInputOutput(element, insideConnector); if (!inputOutput) { var parent = !insideConnector ? extensionElements : getConnector(element); inputOutput = createInputOutput(parent, bpmnFactory, { inputParameters: [], outputParameters: [] }); if (!insideConnector) { commands.push(cmdHelper.addAndRemoveElementsFromList(element, extensionElements, 'values', 'extensionElements', [inputOutput], [])); } else { commands.push(cmdHelper.updateBusinessObject(element, parent, { inputOutput: inputOutput })); } } var newElem = createParameter(type, inputOutput, bpmnFactory, { name: value }); commands.push(cmdHelper.addElementsTolist(element, inputOutput, prop, [newElem])); return commands; }; }; var removeElement = function removeElement(getter, prop, otherProp) { return function (element, extensionElements, value, idx) { var inputOutput = getInputOutput(element, insideConnector); var parameter = getter(element, insideConnector, idx); var commands = []; commands.push(cmdHelper.removeElementsFromList(element, inputOutput, prop, null, [parameter])); var firstLength = inputOutput.get(prop).length - 1; var secondLength = (inputOutput.get(otherProp) || []).length; if (!firstLength && !secondLength) { if (!insideConnector) { commands.push(extensionElementsHelper.removeEntry(getBusinessObject(element), element, inputOutput)); } else { var connector = getConnector(element); commands.push(cmdHelper.updateBusinessObject(element, connector, { inputOutput: undefined })); } } return commands; }; }; var setOptionLabelValue = function setOptionLabelValue(getter) { return function (element, node, option, property, value, idx) { var parameter = getter(element, insideConnector, idx); var suffix = 'Text'; var definition = parameter.get('definition'); if (typeof definition !== 'undefined') { var type = definition.$type; suffix = TYPE_LABEL[type]; } option.text = (value || '') + ' : ' + suffix; }; }; // input parameters /////////////////////////////////////////////////////////////// var inputEntry = extensionElementsEntry(element, bpmnFactory, { id: idPrefix + 'inputs', label: translate('Input Parameters'), modelProperty: 'name', prefix: 'Input', resizable: true, createExtensionElement: newElement('camunda:InputParameter', 'inputParameters'), removeExtensionElement: removeElement(getInputParameter, 'inputParameters', 'outputParameters'), getExtensionElements: function getExtensionElements(element) { return getInputParameters(element, insideConnector); }, onSelectionChange: function onSelectionChange(element, node, event, scope) { outputEntry && outputEntry.deselect(element, node); }, setOptionLabelValue: setOptionLabelValue(getInputParameter) }); entries.push(inputEntry); // output parameters /////////////////////////////////////////////////////// if (ensureOutparameterSupported(element, insideConnector)) { var outputEntry = extensionElementsEntry(element, bpmnFactory, { id: idPrefix + 'outputs', label: translate('Output Parameters'), modelProperty: 'name', prefix: 'Output', resizable: true, createExtensionElement: newElement('camunda:OutputParameter', 'outputParameters'), removeExtensionElement: removeElement(getOutputParameter, 'outputParameters', 'inputParameters'), getExtensionElements: function getExtensionElements(element) { return getOutputParameters(element, insideConnector); }, onSelectionChange: function onSelectionChange(element, node, event, scope) { inputEntry.deselect(element, node); }, setOptionLabelValue: setOptionLabelValue(getOutputParameter) }); entries.push(outputEntry); } return result; }; },{"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../../../../helper/ExtensionElementsHelper":27,"../../../../helper/InputOutputHelper":30,"./ExtensionElements":90,"bpmn-js/lib/util/ModelUtil":216}],97:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is; var elementHelper = require('../../../../helper/ElementHelper'), inputOutputHelper = require('../../../../helper/InputOutputHelper'), cmdHelper = require('../../../../helper/CmdHelper'), utils = require('../../../../Utils'); var entryFactory = require('../../../../factory/EntryFactory'), script = require('./Script')('scriptFormat', 'value', true); function createElement(type, parent, factory, properties) { return elementHelper.createElement(type, properties, parent, factory); } function _isScript(elem) { return is(elem, 'camunda:Script'); } function isList(elem) { return is(elem, 'camunda:List'); } function isMap(elem) { return is(elem, 'camunda:Map'); } function ensureInputOutputSupported(element, insideConnector) { return inputOutputHelper.isInputOutputSupported(element, insideConnector); } module.exports = function (element, bpmnFactory, options, translate) { var typeInfo = { 'camunda:Map': { value: 'map', label: translate('Map') }, 'camunda:List': { value: 'list', label: translate('List') }, 'camunda:Script': { value: 'script', label: translate('Script') } }; options = options || {}; var insideConnector = !!options.insideConnector, idPrefix = options.idPrefix || ''; var getSelected = options.getSelectedParameter; if (!ensureInputOutputSupported(element, insideConnector)) { return []; } var entries = []; var isSelected = function isSelected(element, node) { return getSelected(element, node); }; // parameter name //////////////////////////////////////////////////////// entries.push(entryFactory.validationAwareTextField({ id: idPrefix + 'parameterName', label: 'Name', modelProperty: 'name', getProperty: function getProperty(element, node) { return (getSelected(element, node) || {}).name; }, setProperty: function setProperty(element, values, node) { var param = getSelected(element, node); return cmdHelper.updateBusinessObject(element, param, values); }, validate: function validate(element, values, node) { var bo = getSelected(element, node); var validation = {}; if (bo) { var nameValue = values.name; if (nameValue) { if (utils.containsSpace(nameValue)) { validation.name = 'Name must not contain spaces'; } } else { validation.name = 'Parameter must have a name'; } } return validation; }, hidden: function hidden(element, node) { return !isSelected(element, node); } })); // parameter type ////////////////////////////////////////////////////// var selectOptions = [{ value: 'text', name: 'Text' }, { value: 'script', name: 'Script' }, { value: 'list', name: 'List' }, { value: 'map', name: 'Map' }]; entries.push(entryFactory.selectBox({ id: idPrefix + 'parameterType', label: 'Type', selectOptions: selectOptions, modelProperty: 'parameterType', get: function get(element, node) { var bo = getSelected(element, node); var parameterType = 'text'; if (typeof bo !== 'undefined') { var definition = bo.get('definition'); if (typeof definition !== 'undefined') { var type = definition.$type; parameterType = typeInfo[type].value; } } return { parameterType: parameterType }; }, set: function set(element, values, node) { var bo = getSelected(element, node); var properties = { value: undefined, definition: undefined }; var createParameterTypeElem = function createParameterTypeElem(type) { return createElement(type, bo, bpmnFactory); }; var parameterType = values.parameterType; if (parameterType === 'script') { properties.definition = createParameterTypeElem('camunda:Script'); } else if (parameterType === 'list') { properties.definition = createParameterTypeElem('camunda:List'); } else if (parameterType === 'map') { properties.definition = createParameterTypeElem('camunda:Map'); } return cmdHelper.updateBusinessObject(element, bo, properties); }, show: function show(element, node) { return isSelected(element, node); } })); // parameter value (type = text) /////////////////////////////////////////////////////// entries.push(entryFactory.textBox({ id: idPrefix + 'parameterType-text', label: 'Value', modelProperty: 'value', get: function get(element, node) { return { value: (getSelected(element, node) || {}).value }; }, set: function set(element, values, node) { var param = getSelected(element, node); values.value = values.value || undefined; return cmdHelper.updateBusinessObject(element, param, values); }, show: function show(element, node) { var bo = getSelected(element, node); return bo && !bo.definition; } })); // parameter value (type = script) /////////////////////////////////////////////////////// entries.push({ id: idPrefix + 'parameterType-script', html: '
' + script.template + '
', get: function get(element, node) { var bo = getSelected(element, node); return bo && _isScript(bo.definition) ? script.get(element, bo.definition) : {}; }, set: function set(element, values, node) { var bo = getSelected(element, node); var update = script.set(element, values); return cmdHelper.updateBusinessObject(element, bo.definition, update); }, validate: function validate(element, values, node) { var bo = getSelected(element, node); return bo && _isScript(bo.definition) ? script.validate(element, bo.definition) : {}; }, isScript: function isScript(element, node) { var bo = getSelected(element, node); return bo && _isScript(bo.definition); }, script: script }); // parameter value (type = list) /////////////////////////////////////////////////////// entries.push(entryFactory.table({ id: idPrefix + 'parameterType-list', modelProperties: ['value'], labels: ['Value'], getElements: function getElements(element, node) { var bo = getSelected(element, node); if (bo && isList(bo.definition)) { return bo.definition.items; } return []; }, updateElement: function updateElement(element, values, node, idx) { var bo = getSelected(element, node); var item = bo.definition.items[idx]; return cmdHelper.updateBusinessObject(element, item, values); }, addElement: function addElement(element, node) { var bo = getSelected(element, node); var newValue = createElement('camunda:Value', bo.definition, bpmnFactory, { value: undefined }); return cmdHelper.addElementsTolist(element, bo.definition, 'items', [newValue]); }, removeElement: function removeElement(element, node, idx) { var bo = getSelected(element, node); return cmdHelper.removeElementsFromList(element, bo.definition, 'items', null, [bo.definition.items[idx]]); }, editable: function editable(element, node, prop, idx) { var bo = getSelected(element, node); var item = bo.definition.items[idx]; return !isMap(item) && !isList(item) && !_isScript(item); }, setControlValue: function setControlValue(element, node, input, prop, value, idx) { var bo = getSelected(element, node); var item = bo.definition.items[idx]; if (!isMap(item) && !isList(item) && !_isScript(item)) { input.value = value; } else { input.value = typeInfo[item.$type].label; } }, show: function show(element, node) { var bo = getSelected(element, node); return bo && bo.definition && isList(bo.definition); } })); // parameter value (type = map) /////////////////////////////////////////////////////// entries.push(entryFactory.table({ id: idPrefix + 'parameterType-map', modelProperties: ['key', 'value'], labels: ['Key', 'Value'], addLabel: 'Add Entry', getElements: function getElements(element, node) { var bo = getSelected(element, node); if (bo && isMap(bo.definition)) { return bo.definition.entries; } return []; }, updateElement: function updateElement(element, values, node, idx) { var bo = getSelected(element, node); var entry = bo.definition.entries[idx]; if (isMap(entry.definition) || isList(entry.definition) || _isScript(entry.definition)) { values = { key: values.key }; } return cmdHelper.updateBusinessObject(element, entry, values); }, addElement: function addElement(element, node) { var bo = getSelected(element, node); var newEntry = createElement('camunda:Entry', bo.definition, bpmnFactory, { key: undefined, value: undefined }); return cmdHelper.addElementsTolist(element, bo.definition, 'entries', [newEntry]); }, removeElement: function removeElement(element, node, idx) { var bo = getSelected(element, node); return cmdHelper.removeElementsFromList(element, bo.definition, 'entries', null, [bo.definition.entries[idx]]); }, editable: function editable(element, node, prop, idx) { var bo = getSelected(element, node); var entry = bo.definition.entries[idx]; return prop === 'key' || !isMap(entry.definition) && !isList(entry.definition) && !_isScript(entry.definition); }, setControlValue: function setControlValue(element, node, input, prop, value, idx) { var bo = getSelected(element, node); var entry = bo.definition.entries[idx]; if (prop === 'key' || !isMap(entry.definition) && !isList(entry.definition) && !_isScript(entry.definition)) { input.value = value; } else { input.value = typeInfo[entry.definition.$type].label; } }, show: function show(element, node) { var bo = getSelected(element, node); return bo && bo.definition && isMap(bo.definition); } })); return entries; }; },{"../../../../Utils":5,"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../../../../helper/InputOutputHelper":30,"./Script":104,"bpmn-js/lib/util/ModelUtil":216}],98:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'); var cmdHelper = require('../../../../helper/CmdHelper'); module.exports = function (element, bpmnFactory, options, translate) { var getBusinessObject = options.getBusinessObject; var jobPriorityEntry = entryFactory.textField({ id: 'jobPriority', label: translate('Job Priority'), modelProperty: 'jobPriority', get: function get(element, node) { var bo = getBusinessObject(element); return { jobPriority: bo.get('camunda:jobPriority') }; }, set: function set(element, values) { var bo = getBusinessObject(element); return cmdHelper.updateBusinessObject(element, bo, { 'camunda:jobPriority': values.jobPriority || undefined }); } }); return [jobPriorityEntry]; }; },{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24}],99:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is; var entryFactory = require('../../../../factory/EntryFactory'); var asyncCapableHelper = require('../../../../helper/AsyncCapableHelper'); var elementHelper = require('../../../../helper/ElementHelper'), eventDefinitionHelper = require('../../../../helper/EventDefinitionHelper'), cmdHelper = require('../../../../helper/CmdHelper'); function isAsyncBefore(bo) { return asyncCapableHelper.isAsyncBefore(bo); } function isAsyncAfter(bo) { return asyncCapableHelper.isAsyncAfter(bo); } function getFailedJobRetryTimeCycle(bo) { return asyncCapableHelper.getFailedJobRetryTimeCycle(bo); } function removeFailedJobRetryTimeCycle(bo, element) { return asyncCapableHelper.removeFailedJobRetryTimeCycle(bo, element); } function createExtensionElements(parent, bpmnFactory) { return elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, parent, bpmnFactory); } function createFailedJobRetryTimeCycle(parent, bpmnFactory, cycle) { return elementHelper.createElement('camunda:FailedJobRetryTimeCycle', { body: cycle }, parent, bpmnFactory); } module.exports = function (element, bpmnFactory, options, translate) { var getBusinessObject = options.getBusinessObject; var idPrefix = options.idPrefix || '', labelPrefix = options.labelPrefix || ''; var retryTimeCycleEntry = entryFactory.textField({ id: idPrefix + 'retryTimeCycle', label: labelPrefix + translate('Retry Time Cycle'), modelProperty: 'cycle', get: function get(element, node) { var retryTimeCycle = getFailedJobRetryTimeCycle(getBusinessObject(element)); var value = retryTimeCycle && retryTimeCycle.get('body'); return { cycle: value }; }, set: function set(element, values, node) { var newCycle = values.cycle; var bo = getBusinessObject(element); if (newCycle === '' || typeof newCycle === 'undefined') { // remove retry time cycle element(s) return removeFailedJobRetryTimeCycle(bo, element); } var retryTimeCycle = getFailedJobRetryTimeCycle(bo); if (!retryTimeCycle) { // add new retry time cycle element var commands = []; var extensionElements = bo.get('extensionElements'); if (!extensionElements) { extensionElements = createExtensionElements(bo, bpmnFactory); commands.push(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements })); } retryTimeCycle = createFailedJobRetryTimeCycle(extensionElements, bpmnFactory, newCycle); commands.push(cmdHelper.addAndRemoveElementsFromList(element, extensionElements, 'values', 'extensionElements', [retryTimeCycle], [])); return commands; } // update existing retry time cycle element return cmdHelper.updateBusinessObject(element, retryTimeCycle, { body: newCycle }); }, hidden: function hidden(element) { var bo = getBusinessObject(element); if (bo && (isAsyncBefore(bo) || isAsyncAfter(bo))) { return false; } if (is(element, 'bpmn:Event')) { return !eventDefinitionHelper.getTimerEventDefinition(element); } return true; } }); return [retryTimeCycleEntry]; }; },{"../../../../factory/EntryFactory":14,"../../../../helper/AsyncCapableHelper":23,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../../../../helper/EventDefinitionHelper":26,"bpmn-js/lib/util/ModelUtil":216}],100:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var extensionElementsEntry = require('./ExtensionElements'), extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'), cmdHelper = require('../../../../helper/CmdHelper'), elementHelper = require('../../../../helper/ElementHelper'), ImplementationTypeHelper = require('../../../../helper/ImplementationTypeHelper'); function getListeners(bo, type) { return bo && extensionElementsHelper.getExtensionElements(bo, type) || []; } var CAMUNDA_EXECUTION_LISTENER_ELEMENT = 'camunda:ExecutionListener'; var CAMUNDA_TASK_LISTENER_ELEMENT = 'camunda:TaskListener'; module.exports = function (element, bpmnFactory, options, translate) { var LISTENER_TYPE_LABEL = { class: translate('Java Class'), expression: translate('Expression'), delegateExpression: translate('Delegate Expression'), script: translate('Script') }; var bo; var result = { getSelectedListener: getSelectedListener }; var entries = result.entries = []; var isSequenceFlow = ImplementationTypeHelper.isSequenceFlow(element); function getSelectedListener(element, node) { var selection = executionListenerEntry && executionListenerEntry.getSelected(element, node) || { idx: -1 }; var listener = getListeners(bo, CAMUNDA_EXECUTION_LISTENER_ELEMENT)[selection.idx]; if (!listener && taskListenerEntry) { selection = taskListenerEntry.getSelected(element, node); listener = getListeners(bo, CAMUNDA_TASK_LISTENER_ELEMENT)[selection.idx]; } return listener; } var setOptionLabelValue = function setOptionLabelValue(type) { return function (element, node, option, property, value, idx) { var listeners = getListeners(bo, type); var listener = listeners[idx]; var listenerType = ImplementationTypeHelper.getImplementationType(listener); var event = listener.get('event') ? listener.get('event') : ''; var label = (event || '*') + ' : ' + (LISTENER_TYPE_LABEL[listenerType] || ''); option.text = label; }; }; var newElement = function newElement(element, type, initialEvent) { return function (element, extensionElements, value) { var props = { event: initialEvent, class: '' }; var newElem = elementHelper.createElement(type, props, extensionElements, bpmnFactory); return cmdHelper.addElementsTolist(element, extensionElements, 'values', [newElem]); }; }; var removeElement = function removeElement(element, type) { return function (element, extensionElements, value, idx) { var listeners = getListeners(bo, type); var listener = listeners[idx]; if (listener) { return extensionElementsHelper.removeEntry(bo, element, listener); } }; }; ////////// Execution Listener if (is(element, 'bpmn:FlowElement') || is(element, 'bpmn:Process') || is(element, 'bpmn:Participant')) { bo = getBusinessObject(element); if (is(element, 'bpmn:Participant')) { element = element.processRef; bo = bo.get('processRef'); } if (bo) { var executionListenerEntry = extensionElementsEntry(element, bpmnFactory, { id: 'executionListeners', label: translate('Execution Listener'), modelProperty: 'name', idGeneration: 'false', reference: 'processRef', createExtensionElement: newElement(element, CAMUNDA_EXECUTION_LISTENER_ELEMENT, isSequenceFlow ? 'take' : 'start'), removeExtensionElement: removeElement(element, CAMUNDA_EXECUTION_LISTENER_ELEMENT), getExtensionElements: function getExtensionElements(element) { return getListeners(bo, CAMUNDA_EXECUTION_LISTENER_ELEMENT); }, onSelectionChange: function onSelectionChange(element, node, event, scope) { taskListenerEntry && taskListenerEntry.deselect(element, node); }, setOptionLabelValue: setOptionLabelValue(CAMUNDA_EXECUTION_LISTENER_ELEMENT) }); entries.push(executionListenerEntry); } } ////////// Task Listener if (is(element, 'bpmn:UserTask')) { bo = getBusinessObject(element); var taskListenerEntry = extensionElementsEntry(element, bpmnFactory, { id: 'taskListeners', label: translate('Task Listener'), modelProperty: 'name', idGeneration: 'false', createExtensionElement: newElement(element, CAMUNDA_TASK_LISTENER_ELEMENT, 'create'), removeExtensionElement: removeElement(element, CAMUNDA_TASK_LISTENER_ELEMENT), getExtensionElements: function getExtensionElements(element) { return getListeners(bo, CAMUNDA_TASK_LISTENER_ELEMENT); }, onSelectionChange: function onSelectionChange(element, node, event, scope) { executionListenerEntry.deselect(element, node); }, setOptionLabelValue: setOptionLabelValue(CAMUNDA_TASK_LISTENER_ELEMENT) }); entries.push(taskListenerEntry); } return result; }; },{"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../../../../helper/ExtensionElementsHelper":27,"../../../../helper/ImplementationTypeHelper":29,"./ExtensionElements":90,"bpmn-js/lib/util/ModelUtil":216}],101:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var entryFactory = require('../../../../factory/EntryFactory'); var elementHelper = require('../../../../helper/ElementHelper'), cmdHelper = require('../../../../helper/CmdHelper'); var domClasses = require('min-dom/lib/classes'); /** * Get a property value of the loop characteristics. * * @param {djs.model.Base} element * @param {string} propertyName * * @return {any} the property value */ function getProperty(element, propertyName) { var loopCharacteristics = getLoopCharacteristics(element); return loopCharacteristics && loopCharacteristics.get(propertyName); } /** * Get the body of a given expression. * * @param {ModdleElement} expression * * @return {string} the body (value) of the expression */ function getBody(expression) { return expression && expression.get('body'); } /** * Get the loop characteristics of an element. * * @param {djs.model.Base} element * * @return {ModdleElement} the loop characteristics */ function getLoopCharacteristics(element) { var bo = getBusinessObject(element); return bo.loopCharacteristics; } /** * Get the loop cardinality of the loop characteristics. * * @param {djs.model.Base} element * * @return {ModdleElement} an expression representing the loop cardinality */ function getLoopCardinality(element) { return getProperty(element, 'loopCardinality'); } /** * Get the loop cardinality value of the loop characteristics. * * @param {djs.model.Base} element * * @return {string} the loop cardinality value */ function getLoopCardinalityValue(element) { var loopCardinality = getLoopCardinality(element); return getBody(loopCardinality); } /** * Get the completion condition of the loop characteristics. * * @param {djs.model.Base} element * * @return {ModdleElement} an expression representing the completion condition */ function getCompletionCondition(element) { return getProperty(element, 'completionCondition'); } /** * Get the completion condition value of the loop characteristics. * * @param {djs.model.Base} element * * @return {string} the completion condition value */ function getCompletionConditionValue(element) { var completionCondition = getCompletionCondition(element); return getBody(completionCondition); } /** * Get the 'camunda:collection' attribute value of the loop characteristics. * * @param {djs.model.Base} element * * @return {string} the 'camunda:collection' value */ function getCollection(element) { return getProperty(element, 'camunda:collection'); } /** * Get the 'camunda:elementVariable' attribute value of the loop characteristics. * * @param {djs.model.Base} element * * @return {string} the 'camunda:elementVariable' value */ function getElementVariable(element) { return getProperty(element, 'camunda:elementVariable'); } /** * Creates 'bpmn:FormalExpression' element. * * @param {ModdleElement} parent * @param {string} body * @param {BpmnFactory} bpmnFactory * * @result {ModdleElement} a formal expression */ function createFormalExpression(parent, body, bpmnFactory) { return elementHelper.createElement('bpmn:FormalExpression', { body: body }, parent, bpmnFactory); } /** * Updates a specific formal expression of the loop characteristics. * * @param {djs.model.Base} element * @param {string} propertyName * @param {string} newValue * @param {BpmnFactory} bpmnFactory */ function updateFormalExpression(element, propertyName, newValue, bpmnFactory) { var loopCharacteristics = getLoopCharacteristics(element); var expressionProps = {}; if (!newValue) { // remove formal expression expressionProps[propertyName] = undefined; return cmdHelper.updateBusinessObject(element, loopCharacteristics, expressionProps); } var existingExpression = loopCharacteristics.get(propertyName); if (!existingExpression) { // add formal expression expressionProps[propertyName] = createFormalExpression(loopCharacteristics, newValue, bpmnFactory); return cmdHelper.updateBusinessObject(element, loopCharacteristics, expressionProps); } // edit existing formal expression return cmdHelper.updateBusinessObject(element, existingExpression, { body: newValue }); } module.exports = function (element, bpmnFactory, translate) { var entries = []; // error message ///////////////////////////////////////////////////////////////// entries.push({ id: 'multiInstance-errorMessage', html: '
' + ' ' + translate('Must provide either loop cardinality or collection') + '
', isValid: function isValid(element, node, notification, scope) { var loopCharacteristics = getLoopCharacteristics(element); var isValid = true; if (loopCharacteristics) { var loopCardinality = getLoopCardinalityValue(element); var collection = getCollection(element); isValid = !loopCardinality && !collection; } domClasses(node).toggle('bpp-hidden', !isValid); domClasses(notification).toggle('bpp-error-message', isValid); return isValid; } }); // loop cardinality ////////////////////////////////////////////////////////////// entries.push(entryFactory.textField({ id: 'multiInstance-loopCardinality', label: translate('Loop Cardinality'), modelProperty: 'loopCardinality', get: function get(element, node) { return { loopCardinality: getLoopCardinalityValue(element) }; }, set: function set(element, values) { return updateFormalExpression(element, 'loopCardinality', values.loopCardinality, bpmnFactory); } })); // collection ////////////////////////////////////////////////////////////////// entries.push(entryFactory.textField({ id: 'multiInstance-collection', label: translate('Collection'), modelProperty: 'collection', get: function get(element, node) { return { collection: getCollection(element) }; }, set: function set(element, values) { var loopCharacteristics = getLoopCharacteristics(element); return cmdHelper.updateBusinessObject(element, loopCharacteristics, { 'camunda:collection': values.collection || undefined }); }, validate: function validate(element, values, node) { var collection = getCollection(element); var elementVariable = getElementVariable(element); if (!collection && elementVariable) { return { collection: 'Must provide a value' }; } } })); // element variable //////////////////////////////////////////////////////////// entries.push(entryFactory.textField({ id: 'multiInstance-elementVariable', label: translate('Element Variable'), modelProperty: 'elementVariable', get: function get(element, node) { return { elementVariable: getElementVariable(element) }; }, set: function set(element, values) { var loopCharacteristics = getLoopCharacteristics(element); return cmdHelper.updateBusinessObject(element, loopCharacteristics, { 'camunda:elementVariable': values.elementVariable || undefined }); } })); // Completion Condition ////////////////////////////////////////////////////// entries.push(entryFactory.textField({ id: 'multiInstance-completionCondition', label: translate('Completion Condition'), modelProperty: 'completionCondition', get: function get(element) { return { completionCondition: getCompletionConditionValue(element) }; }, set: function set(element, values) { return updateFormalExpression(element, 'completionCondition', values.completionCondition, bpmnFactory); } })); return entries; }; },{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"bpmn-js/lib/util/ModelUtil":216,"min-dom/lib/classes":106}],102:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, is = require('bpmn-js/lib/util/ModelUtil').is; var factory = require('../../../../factory/EntryFactory'); var elementHelper = require('../../../../helper/ElementHelper'), extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'), cmdHelper = require('../../../../helper/CmdHelper'), utils = require('../../../../Utils'); var assign = require('lodash/object/assign'), forEach = require('lodash/collection/forEach'), find = require('lodash/collection/find'); function generatePropertyId() { return utils.nextId('Property_'); } /** * Get all camunda:property objects for a specific business object * * @param {ModdleElement} parent * * @return {Array} a list of camunda:property objects */ function getPropertyValues(parent) { var properties = parent && getPropertiesElement(parent); if (properties && properties.values) { return properties.values; } return []; } /** * Get all camunda:Properties object for a specific business object * * @param {ModdleElement} parent * * @return {ModdleElement} a camunda:Properties object */ function getPropertiesElement(element) { if (!isExtensionElements(element)) { return element.properties; } else { return getPropertiesElementInsideExtensionElements(element); } } /** * Get first camunda:Properties object for a specific bpmn:ExtensionElements * business object. * * @param {ModdleElement} extensionElements * * @return {ModdleElement} a camunda:Properties object */ function getPropertiesElementInsideExtensionElements(extensionElements) { return find(extensionElements.values, function (elem) { return is(elem, 'camunda:Properties'); }); } /** * Returns true, if the given business object is a bpmn:ExtensionElements. * * @param {ModdleElement} element * * @return {boolean} a boolean value */ function isExtensionElements(element) { return is(element, 'bpmn:ExtensionElements'); } /** * Create a camunda:property entry using tableEntryFactory * * @param {djs.model.Base} element * @param {BpmnFactory} bpmnFactory * @param {Object} options * @param {string} options.id * @param {Array} options.modelProperties * @param {Array} options.labels * @param {function} options.getParent Gets the parent business object * @param {function} options.show Indicate when the entry will be shown, should return boolean */ module.exports = function (element, bpmnFactory, options, translate) { var getParent = options.getParent; var modelProperties = options.modelProperties, createParent = options.createParent; var bo = getBusinessObject(element); if (is(element, 'bpmn:Participant')) { bo = bo.get('processRef'); } // build properties group only when the participant have a processRef if (!bo) { return; } assign(options, { addLabel: translate('Add Property'), getElements: function getElements(element, node) { var parent = getParent(element, node, bo); return getPropertyValues(parent); }, addElement: function addElement(element, node) { var commands = [], parent = getParent(element, node, bo); if (!parent && typeof createParent === 'function') { var result = createParent(element, bo); parent = result.parent; commands.push(result.cmd); } var properties = getPropertiesElement(parent); if (!properties) { properties = elementHelper.createElement('camunda:Properties', {}, parent, bpmnFactory); if (!isExtensionElements(parent)) { commands.push(cmdHelper.updateBusinessObject(element, parent, { 'properties': properties })); } else { commands.push(cmdHelper.addAndRemoveElementsFromList(element, parent, 'values', 'extensionElements', [properties], [])); } } var propertyProps = {}; forEach(modelProperties, function (prop) { propertyProps[prop] = undefined; }); // create id if necessary if (modelProperties.indexOf('id') >= 0) { propertyProps.id = generatePropertyId(); } var property = elementHelper.createElement('camunda:Property', propertyProps, properties, bpmnFactory); commands.push(cmdHelper.addElementsTolist(element, properties, 'values', [property])); return commands; }, updateElement: function updateElement(element, value, node, idx) { var parent = getParent(element, node, bo), property = getPropertyValues(parent)[idx]; forEach(modelProperties, function (prop) { value[prop] = value[prop] || undefined; }); return cmdHelper.updateBusinessObject(element, property, value); }, validate: function validate(element, value, node, idx) { // validate id if necessary if (modelProperties.indexOf('id') >= 0) { var parent = getParent(element, node, bo), properties = getPropertyValues(parent), property = properties[idx]; if (property) { // check if id is valid var validationError = utils.isIdValid(property, value.id); if (validationError) { return { id: validationError }; } } } }, removeElement: function removeElement(element, node, idx) { var commands = [], parent = getParent(element, node, bo), properties = getPropertiesElement(parent), propertyValues = getPropertyValues(parent), currentProperty = propertyValues[idx]; commands.push(cmdHelper.removeElementsFromList(element, properties, 'values', null, [currentProperty])); if (propertyValues.length === 1) { // remove camunda:properties if the last existing property has been removed if (!isExtensionElements(parent)) { commands.push(cmdHelper.updateBusinessObject(element, parent, { properties: undefined })); } else { forEach(parent.values, function (value) { if (is(value, 'camunda:Properties')) { commands.push(extensionElementsHelper.removeEntry(bo, element, value)); } }); } } return commands; } }); return factory.table(options); }; },{"../../../../Utils":5,"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"../../../../helper/ElementHelper":25,"../../../../helper/ExtensionElementsHelper":27,"bpmn-js/lib/util/ModelUtil":216,"lodash/collection/find":421,"lodash/collection/forEach":422,"lodash/object/assign":496}],103:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is; var assign = require('lodash/object/assign'); var entryFactory = require('../../../../factory/EntryFactory'), cmdHelper = require('../../../../helper/CmdHelper'); module.exports = function (element, bpmnFactory, options, translate) { var getBusinessObject = options.getBusinessObject, hideResultVariable = options.hideResultVariable, id = options.id || 'resultVariable'; var resultVariableEntry = entryFactory.textField({ id: id, label: translate('Result Variable'), modelProperty: 'resultVariable', get: function get(element, node) { var bo = getBusinessObject(element); return { resultVariable: bo.get('camunda:resultVariable') }; }, set: function set(element, values, node) { var bo = getBusinessObject(element); var resultVariable = values.resultVariable || undefined; var props = { 'camunda:resultVariable': resultVariable }; if (is(bo, 'camunda:DmnCapable') && !resultVariable) { props = assign({ 'camunda:mapDecisionResult': 'resultList' }, props); } return cmdHelper.updateBusinessObject(element, bo, props); }, hidden: function hidden(element, node) { if (typeof hideResultVariable === 'function') { return hideResultVariable.apply(resultVariableEntry, arguments); } } }); return [resultVariableEntry]; }; },{"../../../../factory/EntryFactory":14,"../../../../helper/CmdHelper":24,"bpmn-js/lib/util/ModelUtil":216,"lodash/object/assign":496}],104:[function(require,module,exports){ 'use strict'; var domQuery = require('min-dom/lib/query'), utils = require('../../../../Utils'); function getScriptType(node) { return utils.selectedType('select[name=scriptType]', node.parentElement); } module.exports = function (scriptLanguagePropName, scriptValuePropName, isFormatRequired) { return { template: '
' + '' + '
' + '' + '' + '
' + '
' + '
' + '' + '
' + '' + '
' + '
' + '
' + '' + '
' + '' + '' + '
' + '
' + '
' + '' + '
' + '' + '
' + '
', get: function get(element, bo) { var values = {}; // read values from xml: var boScriptResource = bo.get('camunda:resource'), boScript = bo.get(scriptValuePropName), boScriptFormat = bo.get(scriptLanguagePropName); if (typeof boScriptResource !== 'undefined') { values.scriptResourceValue = boScriptResource; values.scriptType = 'scriptResource'; } else { values.scriptValue = boScript; values.scriptType = 'script'; } values.scriptFormat = boScriptFormat; return values; }, set: function set(element, values, containerElement) { var scriptFormat = values.scriptFormat, scriptType = values.scriptType, scriptResourceValue = values.scriptResourceValue, scriptValue = values.scriptValue; // init update var update = { 'camunda:resource': undefined }; update[scriptValuePropName] = undefined; update[scriptLanguagePropName] = undefined; if (isFormatRequired) { // always set language update[scriptLanguagePropName] = scriptFormat || ''; } else // set language only when scriptFormat has a value if (scriptFormat !== '') { update[scriptLanguagePropName] = scriptFormat; } // set either inline script or resource if ('scriptResource' === scriptType) { update['camunda:resource'] = scriptResourceValue || ''; } else { update[scriptValuePropName] = scriptValue || ''; } return update; }, validate: function validate(element, values) { var validationResult = {}; if (values.scriptType === 'script' && !values.scriptValue) { validationResult.scriptValue = 'Must provide a value'; } if (values.scriptType === 'scriptResource' && !values.scriptResourceValue) { validationResult.scriptResourceValue = 'Must provide a value'; } if (isFormatRequired && (!values.scriptFormat || values.scriptFormat.length === 0)) { validationResult.scriptFormat = 'Must provide a value'; } return validationResult; }, clearScriptFormat: function clearScriptFormat(element, inputNode, btnNode, scopeNode) { domQuery('input[name=scriptFormat]', scopeNode).value = ''; return true; }, canClearScriptFormat: function canClearScriptFormat(element, inputNode, btnNode, scopeNode) { var input = domQuery('input[name=scriptFormat]', scopeNode); return input.value !== ''; }, clearScriptResource: function clearScriptResource(element, inputNode, btnNode, scopeNode) { domQuery('input[name=scriptResourceValue]', scopeNode).value = ''; return true; }, canClearScriptResource: function canClearScriptResource(element, inputNode, btnNode, scopeNode) { var input = domQuery('input[name=scriptResourceValue]', scopeNode); return input.value !== ''; }, clearScript: function clearScript(element, inputNode, btnNode, scopeNode) { domQuery('textarea[name=scriptValue]', scopeNode).value = ''; return true; }, canClearScript: function canClearScript(element, inputNode, btnNode, scopeNode) { var input = domQuery('textarea[name=scriptValue]', scopeNode); return input.value !== ''; }, isScriptResource: function isScriptResource(element, inputNode, btnNode, scopeNode) { var scriptType = getScriptType(scopeNode); return scriptType === 'scriptResource'; }, isScript: function isScript(element, inputNode, btnNode, scopeNode) { var scriptType = getScriptType(scopeNode); return scriptType === 'script'; } }; }; },{"../../../../Utils":5,"min-dom/lib/query":112}],105:[function(require,module,exports){ "use strict"; /** * Set attribute `name` to `val`, or get attr `name`. * * @param {Element} el * @param {String} name * @param {String} [val] * @api public */ module.exports = function (el, name, val) { // get if (arguments.length == 2) { return el.getAttribute(name); } // remove if (val === null) { return el.removeAttribute(name); } // set el.setAttribute(name, val); return el; }; },{}],106:[function(require,module,exports){ 'use strict'; module.exports = require('component-classes'); },{"component-classes":230}],107:[function(require,module,exports){ "use strict"; module.exports = function (el) { var c; while (el.childNodes.length) { c = el.childNodes[0]; el.removeChild(c); } return el; }; },{}],108:[function(require,module,exports){ 'use strict'; module.exports = require('component-closest'); },{"component-closest":231}],109:[function(require,module,exports){ 'use strict'; module.exports = require('component-delegate'); },{"component-delegate":232}],110:[function(require,module,exports){ 'use strict'; module.exports = require('domify'); },{"domify":411}],111:[function(require,module,exports){ 'use strict'; module.exports = require('component-matches-selector'); },{"component-matches-selector":235}],112:[function(require,module,exports){ 'use strict'; module.exports = require('component-query'); },{"component-query":236}],113:[function(require,module,exports){ "use strict"; module.exports = function (el) { el.parentNode && el.parentNode.removeChild(el); }; },{}],114:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Modeler; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _ids = require('ids'); var _ids2 = _interopRequireDefault(_ids); var _Viewer = require('./Viewer'); var _Viewer2 = _interopRequireDefault(_Viewer); var _NavigatedViewer = require('./NavigatedViewer'); var _NavigatedViewer2 = _interopRequireDefault(_NavigatedViewer); var _keyboardMove = require('diagram-js/lib/navigation/keyboard-move'); var _keyboardMove2 = _interopRequireDefault(_keyboardMove); var _movecanvas = require('diagram-js/lib/navigation/movecanvas'); var _movecanvas2 = _interopRequireDefault(_movecanvas); var _touch = require('diagram-js/lib/navigation/touch'); var _touch2 = _interopRequireDefault(_touch); var _zoomscroll = require('diagram-js/lib/navigation/zoomscroll'); var _zoomscroll2 = _interopRequireDefault(_zoomscroll); var _alignElements = require('diagram-js/lib/features/align-elements'); var _alignElements2 = _interopRequireDefault(_alignElements); var _autoPlace = require('./features/auto-place'); var _autoPlace2 = _interopRequireDefault(_autoPlace); var _autoResize = require('./features/auto-resize'); var _autoResize2 = _interopRequireDefault(_autoResize); var _autoScroll = require('diagram-js/lib/features/auto-scroll'); var _autoScroll2 = _interopRequireDefault(_autoScroll); var _bendpoints = require('diagram-js/lib/features/bendpoints'); var _bendpoints2 = _interopRequireDefault(_bendpoints); var _contextPad = require('./features/context-pad'); var _contextPad2 = _interopRequireDefault(_contextPad); var _copyPaste = require('./features/copy-paste'); var _copyPaste2 = _interopRequireDefault(_copyPaste); var _distributeElements = require('./features/distribute-elements'); var _distributeElements2 = _interopRequireDefault(_distributeElements); var _editorActions = require('./features/editor-actions'); var _editorActions2 = _interopRequireDefault(_editorActions); var _keyboard = require('./features/keyboard'); var _keyboard2 = _interopRequireDefault(_keyboard); var _keyboardMoveSelection = require('diagram-js/lib/features/keyboard-move-selection'); var _keyboardMoveSelection2 = _interopRequireDefault(_keyboardMoveSelection); var _labelEditing = require('./features/label-editing'); var _labelEditing2 = _interopRequireDefault(_labelEditing); var _modeling = require('./features/modeling'); var _modeling2 = _interopRequireDefault(_modeling); var _move = require('diagram-js/lib/features/move'); var _move2 = _interopRequireDefault(_move); var _palette = require('./features/palette'); var _palette2 = _interopRequireDefault(_palette); var _replacePreview = require('./features/replace-preview'); var _replacePreview2 = _interopRequireDefault(_replacePreview); var _resize = require('diagram-js/lib/features/resize'); var _resize2 = _interopRequireDefault(_resize); var _snapping = require('./features/snapping'); var _snapping2 = _interopRequireDefault(_snapping); var _search = require('./features/search'); var _search2 = _interopRequireDefault(_search); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var initialDiagram = '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + ''; /** * A modeler for BPMN 2.0 diagrams. * * * ## Extending the Modeler * * In order to extend the viewer pass extension modules to bootstrap via the * `additionalModules` option. An extension module is an object that exposes * named services. * * The following example depicts the integration of a simple * logging component that integrates with interaction events: * * * ```javascript * * // logging component * function InteractionLogger(eventBus) { * eventBus.on('element.hover', function(event) { * console.log() * }) * } * * InteractionLogger.$inject = [ 'eventBus' ]; // minification save * * // extension module * var extensionModule = { * __init__: [ 'interactionLogger' ], * interactionLogger: [ 'type', InteractionLogger ] * }; * * // extend the viewer * var bpmnModeler = new Modeler({ additionalModules: [ extensionModule ] }); * bpmnModeler.importXML(...); * ``` * * * ## Customizing / Replacing Components * * You can replace individual diagram components by redefining them in override modules. * This works for all components, including those defined in the core. * * Pass in override modules via the `options.additionalModules` flag like this: * * ```javascript * function CustomContextPadProvider(contextPad) { * * contextPad.registerProvider(this); * * this.getContextPadEntries = function(element) { * // no entries, effectively disable the context pad * return {}; * }; * } * * CustomContextPadProvider.$inject = [ 'contextPad' ]; * * var overrideModule = { * contextPadProvider: [ 'type', CustomContextPadProvider ] * }; * * var bpmnModeler = new Modeler({ additionalModules: [ overrideModule ]}); * ``` * * @param {Object} [options] configuration options to pass to the viewer * @param {DOMElement} [options.container] the container to render the viewer in, defaults to body. * @param {String|Number} [options.width] the width of the viewer * @param {String|Number} [options.height] the height of the viewer * @param {Object} [options.moddleExtensions] extension packages to provide * @param {Array} [options.modules] a list of modules to override the default modules * @param {Array} [options.additionalModules] a list of modules to use with the default modules */ function Modeler(options) { _Viewer2.default.call(this, options); // hook ID collection into the modeler this.on('import.parse.complete', function (event) { if (!event.error) { this._collectIds(event.definitions, event.context); } }, this); this.on('diagram.destroy', function () { this.get('moddle').ids.clear(); }, this); } (0, _inherits2.default)(Modeler, _Viewer2.default); Modeler.Viewer = _Viewer2.default; Modeler.NavigatedViewer = _NavigatedViewer2.default; /** * Create a new diagram to start modeling. * * @param {Function} [done] */ Modeler.prototype.createDiagram = function (done) { return this.importXML(initialDiagram, done); }; /** * Create a moddle instance, attaching ids to it. * * @param {Object} options */ Modeler.prototype._createModdle = function (options) { var moddle = _Viewer2.default.prototype._createModdle.call(this, options); // attach ids to moddle to be able to track // and validated ids in the BPMN 2.0 XML document // tree moddle.ids = new _ids2.default([32, 36, 1]); return moddle; }; /** * Collect ids processed during parsing of the * definitions object. * * @param {ModdleElement} definitions * @param {Context} context */ Modeler.prototype._collectIds = function (definitions, context) { var moddle = definitions.$model, ids = moddle.ids, id; // remove references from previous import ids.clear(); for (id in context.elementsById) { ids.claim(id, context.elementsById[id]); } }; Modeler.prototype._interactionModules = [ // non-modeling components _keyboardMove2.default, _movecanvas2.default, _touch2.default, _zoomscroll2.default]; Modeler.prototype._modelingModules = [ // modeling components _alignElements2.default, _autoPlace2.default, _autoScroll2.default, _autoResize2.default, _bendpoints2.default, _contextPad2.default, _copyPaste2.default, _distributeElements2.default, _editorActions2.default, _keyboard2.default, _keyboardMoveSelection2.default, _labelEditing2.default, _modeling2.default, _move2.default, _palette2.default, _replacePreview2.default, _resize2.default, _snapping2.default, _search2.default]; // modules the modeler is composed of // // - viewer modules // - interaction modules // - modeling modules Modeler.prototype._modules = [].concat(Modeler.prototype._modules, Modeler.prototype._interactionModules, Modeler.prototype._modelingModules); },{"./NavigatedViewer":115,"./Viewer":116,"./features/auto-place":126,"./features/auto-resize":129,"./features/context-pad":131,"./features/copy-paste":133,"./features/distribute-elements":135,"./features/editor-actions":137,"./features/keyboard":139,"./features/label-editing":144,"./features/modeling":187,"./features/palette":193,"./features/replace-preview":198,"./features/search":205,"./features/snapping":208,"diagram-js/lib/features/align-elements":257,"diagram-js/lib/features/auto-scroll":263,"diagram-js/lib/features/bendpoints":269,"diagram-js/lib/features/keyboard-move-selection":296,"diagram-js/lib/features/move":334,"diagram-js/lib/features/resize":352,"diagram-js/lib/navigation/keyboard-move":384,"diagram-js/lib/navigation/movecanvas":386,"diagram-js/lib/navigation/touch":387,"diagram-js/lib/navigation/zoomscroll":390,"ids":414,"inherits":415}],115:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = NavigatedViewer; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _Viewer = require('./Viewer'); var _Viewer2 = _interopRequireDefault(_Viewer); var _keyboardMove = require('diagram-js/lib/navigation/keyboard-move'); var _keyboardMove2 = _interopRequireDefault(_keyboardMove); var _movecanvas = require('diagram-js/lib/navigation/movecanvas'); var _movecanvas2 = _interopRequireDefault(_movecanvas); var _zoomscroll = require('diagram-js/lib/navigation/zoomscroll'); var _zoomscroll2 = _interopRequireDefault(_zoomscroll); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A viewer that includes mouse navigation facilities * * @param {Object} options */ function NavigatedViewer(options) { _Viewer2.default.call(this, options); } (0, _inherits2.default)(NavigatedViewer, _Viewer2.default); NavigatedViewer.prototype._navigationModules = [_keyboardMove2.default, _movecanvas2.default, _zoomscroll2.default]; NavigatedViewer.prototype._modules = [].concat(NavigatedViewer.prototype._modules, NavigatedViewer.prototype._navigationModules); },{"./Viewer":116,"diagram-js/lib/navigation/keyboard-move":384,"diagram-js/lib/navigation/movecanvas":386,"diagram-js/lib/navigation/zoomscroll":390,"inherits":415}],116:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Viewer; var _minDash = require('min-dash'); var _minDom = require('min-dom'); var _tinySvg = require('tiny-svg'); var _diagramJs = require('diagram-js'); var _diagramJs2 = _interopRequireDefault(_diagramJs); var _bpmnModdle = require('bpmn-moddle'); var _bpmnModdle2 = _interopRequireDefault(_bpmnModdle); var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _Importer = require('./import/Importer'); var _core = require('./core'); var _core2 = _interopRequireDefault(_core); var _translate = require('diagram-js/lib/i18n/translate'); var _translate2 = _interopRequireDefault(_translate); var _selection = require('diagram-js/lib/features/selection'); var _selection2 = _interopRequireDefault(_selection); var _overlays = require('diagram-js/lib/features/overlays'); var _overlays2 = _interopRequireDefault(_overlays); var _PoweredByUtil = require('./util/PoweredByUtil'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function checkValidationError(err) { // check if we can help the user by indicating wrong BPMN 2.0 xml // (in case he or the exporting tool did not get that right) var pattern = /unparsable content <([^>]+)> detected([\s\S]*)$/; var match = pattern.exec(err.message); if (match) { err.message = 'unparsable content <' + match[1] + '> detected; ' + 'this may indicate an invalid BPMN 2.0 diagram file' + match[2]; } return err; } /** * The code in the area * must not be changed. * * @see http://bpmn.io/license for more information. */ var DEFAULT_OPTIONS = { width: '100%', height: '100%', position: 'relative' }; /** * Ensure the passed argument is a proper unit (defaulting to px) */ function ensureUnit(val) { return val + ((0, _minDash.isNumber)(val) ? 'px' : ''); } /** * A viewer for BPMN 2.0 diagrams. * * Have a look at {@link NavigatedViewer} or {@link Modeler} for bundles that include * additional features. * * * ## Extending the Viewer * * In order to extend the viewer pass extension modules to bootstrap via the * `additionalModules` option. An extension module is an object that exposes * named services. * * The following example depicts the integration of a simple * logging component that integrates with interaction events: * * * ```javascript * * // logging component * function InteractionLogger(eventBus) { * eventBus.on('element.hover', function(event) { * console.log() * }) * } * * InteractionLogger.$inject = [ 'eventBus' ]; // minification save * * // extension module * var extensionModule = { * __init__: [ 'interactionLogger' ], * interactionLogger: [ 'type', InteractionLogger ] * }; * * // extend the viewer * var bpmnViewer = new Viewer({ additionalModules: [ extensionModule ] }); * bpmnViewer.importXML(...); * ``` * * @param {Object} [options] configuration options to pass to the viewer * @param {DOMElement} [options.container] the container to render the viewer in, defaults to body. * @param {String|Number} [options.width] the width of the viewer * @param {String|Number} [options.height] the height of the viewer * @param {Object} [options.moddleExtensions] extension packages to provide * @param {Array} [options.modules] a list of modules to override the default modules * @param {Array} [options.additionalModules] a list of modules to use with the default modules */ function Viewer(options) { options = (0, _minDash.assign)({}, DEFAULT_OPTIONS, options); this._moddle = this._createModdle(options); this._container = this._createContainer(options); /* */ addProjectLogo(this._container); /* */ this._init(this._container, this._moddle, options); } (0, _inherits2.default)(Viewer, _diagramJs2.default); /** * Parse and render a BPMN 2.0 diagram. * * Once finished the viewer reports back the result to the * provided callback function with (err, warnings). * * ## Life-Cycle Events * * During import the viewer will fire life-cycle events: * * * import.parse.start (about to read model from xml) * * import.parse.complete (model read; may have worked or not) * * import.render.start (graphical import start) * * import.render.complete (graphical import finished) * * import.done (everything done) * * You can use these events to hook into the life-cycle. * * @param {String} xml the BPMN 2.0 xml * @param {Function} [done] invoked with (err, warnings=[]) */ Viewer.prototype.importXML = function (xml, done) { // done is optional done = done || function () {}; var self = this; // hook in pre-parse listeners + // allow xml manipulation xml = this._emit('import.parse.start', { xml: xml }) || xml; this._moddle.fromXML(xml, 'bpmn:Definitions', function (err, definitions, context) { // hook in post parse listeners + // allow definitions manipulation definitions = self._emit('import.parse.complete', { error: err, definitions: definitions, context: context }) || definitions; var parseWarnings = context.warnings; if (err) { err = checkValidationError(err); self._emit('import.done', { error: err, warnings: parseWarnings }); return done(err, parseWarnings); } self.importDefinitions(definitions, function (err, importWarnings) { var allWarnings = [].concat(parseWarnings, importWarnings || []); self._emit('import.done', { error: err, warnings: allWarnings }); done(err, allWarnings); }); }); }; /** * Export the currently displayed BPMN 2.0 diagram as * a BPMN 2.0 XML document. * * ## Life-Cycle Events * * During XML saving the viewer will fire life-cycle events: * * * saveXML.start (before serialization) * * saveXML.serialized (after xml generation) * * saveXML.done (everything done) * * You can use these events to hook into the life-cycle. * * @param {Object} [options] export options * @param {Boolean} [options.format=false] output formated XML * @param {Boolean} [options.preamble=true] output preamble * * @param {Function} done invoked with (err, xml) */ Viewer.prototype.saveXML = function (options, done) { if (!done) { done = options; options = {}; } var self = this; var definitions = this._definitions; if (!definitions) { return done(new Error('no definitions loaded')); } // allow to fiddle around with definitions definitions = this._emit('saveXML.start', { definitions: definitions }) || definitions; this._moddle.toXML(definitions, options, function (err, xml) { try { xml = self._emit('saveXML.serialized', { error: err, xml: xml }) || xml; self._emit('saveXML.done', { error: err, xml: xml }); } catch (e) { console.error('error in saveXML life-cycle listener', e); } done(err, xml); }); }; /** * Export the currently displayed BPMN 2.0 diagram as * an SVG image. * * ## Life-Cycle Events * * During SVG saving the viewer will fire life-cycle events: * * * saveSVG.start (before serialization) * * saveSVG.done (everything done) * * You can use these events to hook into the life-cycle. * * @param {Object} [options] * @param {Function} done invoked with (err, svgStr) */ Viewer.prototype.saveSVG = function (options, done) { if (!done) { done = options; options = {}; } this._emit('saveSVG.start'); var svg, err; try { var canvas = this.get('canvas'); var contentNode = canvas.getDefaultLayer(), defsNode = (0, _minDom.query)('defs', canvas._svg); var contents = (0, _tinySvg.innerSVG)(contentNode), defs = defsNode ? '' + (0, _tinySvg.innerSVG)(defsNode) + '' : ''; var bbox = contentNode.getBBox(); svg = '\n' + '\n' + '\n' + '' + defs + contents + ''; } catch (e) { err = e; } this._emit('saveSVG.done', { error: err, svg: svg }); done(err, svg); }; /** * Get a named diagram service. * * @example * * var elementRegistry = viewer.get('elementRegistry'); * var startEventShape = elementRegistry.get('StartEvent_1'); * * @param {String} name * * @return {Object} diagram service instance * * @method Viewer#get */ /** * Invoke a function in the context of this viewer. * * @example * * viewer.invoke(function(elementRegistry) { * var startEventShape = elementRegistry.get('StartEvent_1'); * }); * * @param {Function} fn to be invoked * * @return {Object} the functions return value * * @method Viewer#invoke */ /** * Remove all drawn elements from the viewer. * * After calling this method the viewer can still * be reused for opening another diagram. * * @method Viewer#clear */ Viewer.prototype.importDefinitions = function (definitions, done) { // catch synchronous exceptions during #clear() try { if (this._definitions) { // clear existing rendered diagram this.clear(); } // update definitions this._definitions = definitions; } catch (e) { return done(e); } // perform graphical import return (0, _Importer.importBpmnDiagram)(this, definitions, done); }; Viewer.prototype.getModules = function () { return this._modules; }; /** * Destroy the viewer instance and remove all its * remainders from the document tree. */ Viewer.prototype.destroy = function () { // diagram destroy _diagramJs2.default.prototype.destroy.call(this); // dom detach (0, _minDom.remove)(this._container); }; /** * Register an event listener * * Remove a previously added listener via {@link #off(event, callback)}. * * @param {String} event * @param {Number} [priority] * @param {Function} callback * @param {Object} [that] */ Viewer.prototype.on = function (event, priority, callback, target) { return this.get('eventBus').on(event, priority, callback, target); }; /** * De-register an event listener * * @param {String} event * @param {Function} callback */ Viewer.prototype.off = function (event, callback) { this.get('eventBus').off(event, callback); }; Viewer.prototype.attachTo = function (parentNode) { if (!parentNode) { throw new Error('parentNode required'); } // ensure we detach from the // previous, old parent this.detach(); // unwrap jQuery if provided if (parentNode.get && parentNode.constructor.prototype.jquery) { parentNode = parentNode.get(0); } if (typeof parentNode === 'string') { parentNode = (0, _minDom.query)(parentNode); } parentNode.appendChild(this._container); this._emit('attach', {}); this.get('canvas').resized(); }; Viewer.prototype.getDefinitions = function () { return this._definitions; }; Viewer.prototype.detach = function () { var container = this._container, parentNode = container.parentNode; if (!parentNode) { return; } this._emit('detach', {}); parentNode.removeChild(container); }; Viewer.prototype._init = function (container, moddle, options) { var baseModules = options.modules || this.getModules(), additionalModules = options.additionalModules || [], staticModules = [{ bpmnjs: ['value', this], moddle: ['value', moddle] }]; var diagramModules = [].concat(staticModules, baseModules, additionalModules); var diagramOptions = (0, _minDash.assign)((0, _minDash.omit)(options, ['additionalModules']), { canvas: (0, _minDash.assign)({}, options.canvas, { container: container }), modules: diagramModules }); // invoke diagram constructor _diagramJs2.default.call(this, diagramOptions); if (options && options.container) { this.attachTo(options.container); } }; /** * Emit an event on the underlying {@link EventBus} * * @param {String} type * @param {Object} event * * @return {Object} event processing result (if any) */ Viewer.prototype._emit = function (type, event) { return this.get('eventBus').fire(type, event); }; Viewer.prototype._createContainer = function (options) { var container = (0, _minDom.domify)('
'); (0, _minDash.assign)(container.style, { width: ensureUnit(options.width), height: ensureUnit(options.height), position: options.position }); return container; }; Viewer.prototype._createModdle = function (options) { var moddleOptions = (0, _minDash.assign)({}, this._moddleExtensions, options.moddleExtensions); return new _bpmnModdle2.default(moddleOptions); }; // modules the viewer is composed of Viewer.prototype._modules = [_core2.default, _translate2.default, _selection2.default, _overlays2.default]; // default moddle extensions the viewer is composed of Viewer.prototype._moddleExtensions = {}; /* */ /** * Adds the project logo to the diagram container as * required by the bpmn.io license. * * @see http://bpmn.io/license * * @param {Element} container */ function addProjectLogo(container) { var img = _PoweredByUtil.BPMNIO_IMG; var linkMarkup = '' + img + ''; var linkElement = (0, _minDom.domify)(linkMarkup); container.appendChild(linkElement); _minDom.event.bind(linkElement, 'click', function (event) { (0, _PoweredByUtil.open)(); event.preventDefault(); }); } /* */ },{"./core":117,"./import/Importer":211,"./util/PoweredByUtil":217,"bpmn-moddle":220,"diagram-js":241,"diagram-js/lib/features/overlays":339,"diagram-js/lib/features/selection":361,"diagram-js/lib/i18n/translate":376,"inherits":415,"min-dash":505,"min-dom":506,"tiny-svg":535}],117:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _draw = require('../draw'); var _draw2 = _interopRequireDefault(_draw); var _import = require('../import'); var _import2 = _interopRequireDefault(_import); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_draw2.default, _import2.default] }; },{"../draw":122,"../import":213}],118:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.isTypedEvent = isTypedEvent; exports.isThrowEvent = isThrowEvent; exports.isCollection = isCollection; exports.getDi = getDi; exports.getSemantic = getSemantic; exports.getFillColor = getFillColor; exports.getStrokeColor = getStrokeColor; exports.getCirclePath = getCirclePath; exports.getRoundRectPath = getRoundRectPath; exports.getDiamondPath = getDiamondPath; exports.getRectPath = getRectPath; var _minDash = require('min-dash'); var _RenderUtil = require('diagram-js/lib/util/RenderUtil'); // element utils ////////////////////// /** * Checks if eventDefinition of the given element matches with semantic type. * * @return {boolean} true if element is of the given semantic type */ function isTypedEvent(event, eventDefinitionType, filter) { function matches(definition, filter) { return (0, _minDash.every)(filter, function (val, key) { // we want a == conversion here, to be able to catch // undefined == false and friends /* jshint -W116 */ return definition[key] == val; }); } return (0, _minDash.some)(event.eventDefinitions, function (definition) { return definition.$type === eventDefinitionType && matches(event, filter); }); } function isThrowEvent(event) { return event.$type === 'bpmn:IntermediateThrowEvent' || event.$type === 'bpmn:EndEvent'; } function isCollection(element) { var dataObject = element.dataObjectRef; return element.isCollection || dataObject && dataObject.isCollection; } function getDi(element) { return element.businessObject.di; } function getSemantic(element) { return element.businessObject; } // color access ////////////////////// function getFillColor(element, defaultColor) { return getDi(element).get('bioc:fill') || defaultColor || 'white'; } function getStrokeColor(element, defaultColor) { return getDi(element).get('bioc:stroke') || defaultColor || 'black'; } // cropping path customizations ////////////////////// function getCirclePath(shape) { var cx = shape.x + shape.width / 2, cy = shape.y + shape.height / 2, radius = shape.width / 2; var circlePath = [['M', cx, cy], ['m', 0, -radius], ['a', radius, radius, 0, 1, 1, 0, 2 * radius], ['a', radius, radius, 0, 1, 1, 0, -2 * radius], ['z']]; return (0, _RenderUtil.componentsToPath)(circlePath); } function getRoundRectPath(shape, borderRadius) { var x = shape.x, y = shape.y, width = shape.width, height = shape.height; var roundRectPath = [['M', x + borderRadius, y], ['l', width - borderRadius * 2, 0], ['a', borderRadius, borderRadius, 0, 0, 1, borderRadius, borderRadius], ['l', 0, height - borderRadius * 2], ['a', borderRadius, borderRadius, 0, 0, 1, -borderRadius, borderRadius], ['l', borderRadius * 2 - width, 0], ['a', borderRadius, borderRadius, 0, 0, 1, -borderRadius, -borderRadius], ['l', 0, borderRadius * 2 - height], ['a', borderRadius, borderRadius, 0, 0, 1, borderRadius, -borderRadius], ['z']]; return (0, _RenderUtil.componentsToPath)(roundRectPath); } function getDiamondPath(shape) { var width = shape.width, height = shape.height, x = shape.x, y = shape.y, halfWidth = width / 2, halfHeight = height / 2; var diamondPath = [['M', x + halfWidth, y], ['l', halfWidth, halfHeight], ['l', -halfWidth, halfHeight], ['l', -halfWidth, -halfHeight], ['z']]; return (0, _RenderUtil.componentsToPath)(diamondPath); } function getRectPath(shape) { var x = shape.x, y = shape.y, width = shape.width, height = shape.height; var rectPath = [['M', x, y], ['l', width, 0], ['l', 0, height], ['l', -width, 0], ['z']]; return (0, _RenderUtil.componentsToPath)(rectPath); } },{"diagram-js/lib/util/RenderUtil":407,"min-dash":505}],119:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnRenderer; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _minDash = require('min-dash'); var _BaseRenderer = require('diagram-js/lib/draw/BaseRenderer'); var _BaseRenderer2 = _interopRequireDefault(_BaseRenderer); var _DiUtil = require('../util/DiUtil'); var _ModelUtil = require('../util/ModelUtil'); var _RenderUtil = require('diagram-js/lib/util/RenderUtil'); var _BpmnRenderUtil = require('./BpmnRenderUtil'); var _minDom = require('min-dom'); var _tinySvg = require('tiny-svg'); var _SvgTransformUtil = require('diagram-js/lib/util/SvgTransformUtil'); var _ids = require('ids'); var _ids2 = _interopRequireDefault(_ids); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var RENDERER_IDS = new _ids2.default(); var TASK_BORDER_RADIUS = 10; var INNER_OUTER_DIST = 3; var DEFAULT_FILL_OPACITY = .95, HIGH_FILL_OPACITY = .35; function BpmnRenderer(config, eventBus, styles, pathMap, canvas, textRenderer, priority) { _BaseRenderer2.default.call(this, eventBus, priority); var defaultFillColor = config && config.defaultFillColor, defaultStrokeColor = config && config.defaultStrokeColor; var rendererId = RENDERER_IDS.next(); var markers = {}; var computeStyle = styles.computeStyle; function addMarker(id, options) { var attrs = (0, _minDash.assign)({ fill: 'black', strokeWidth: 1, strokeLinecap: 'round', strokeDasharray: 'none' }, options.attrs); var ref = options.ref || { x: 0, y: 0 }; var scale = options.scale || 1; // fix for safari / chrome / firefox bug not correctly // resetting stroke dash array if (attrs.strokeDasharray === 'none') { attrs.strokeDasharray = [10000, 1]; } var marker = (0, _tinySvg.create)('marker'); (0, _tinySvg.attr)(options.element, attrs); (0, _tinySvg.append)(marker, options.element); (0, _tinySvg.attr)(marker, { id: id, viewBox: '0 0 20 20', refX: ref.x, refY: ref.y, markerWidth: 20 * scale, markerHeight: 20 * scale, orient: 'auto' }); var defs = (0, _minDom.query)('defs', canvas._svg); if (!defs) { defs = (0, _tinySvg.create)('defs'); (0, _tinySvg.append)(canvas._svg, defs); } (0, _tinySvg.append)(defs, marker); markers[id] = marker; } function marker(type, fill, stroke) { var id = type + '-' + fill + '-' + stroke + '-' + rendererId; if (!markers[id]) { createMarker(type, fill, stroke); } return 'url(#' + id + ')'; } function createMarker(type, fill, stroke) { var id = type + '-' + fill + '-' + stroke + '-' + rendererId; if (type === 'sequenceflow-end') { var sequenceflowEnd = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(sequenceflowEnd, { d: 'M 1 5 L 11 10 L 1 15 Z' }); addMarker(id, { element: sequenceflowEnd, ref: { x: 11, y: 10 }, scale: 0.5, attrs: { fill: stroke, stroke: stroke } }); } if (type === 'messageflow-start') { var messageflowStart = (0, _tinySvg.create)('circle'); (0, _tinySvg.attr)(messageflowStart, { cx: 6, cy: 6, r: 3.5 }); addMarker(id, { element: messageflowStart, attrs: { fill: fill, stroke: stroke }, ref: { x: 6, y: 6 } }); } if (type === 'messageflow-end') { var messageflowEnd = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(messageflowEnd, { d: 'm 1 5 l 0 -3 l 7 3 l -7 3 z' }); addMarker(id, { element: messageflowEnd, attrs: { fill: fill, stroke: stroke, strokeLinecap: 'butt' }, ref: { x: 8.5, y: 5 } }); } if (type === 'association-start') { var associationStart = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(associationStart, { d: 'M 11 5 L 1 10 L 11 15' }); addMarker(id, { element: associationStart, attrs: { fill: 'none', stroke: stroke, strokeWidth: 1.5 }, ref: { x: 1, y: 10 }, scale: 0.5 }); } if (type === 'association-end') { var associationEnd = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(associationEnd, { d: 'M 1 5 L 11 10 L 1 15' }); addMarker(id, { element: associationEnd, attrs: { fill: 'none', stroke: stroke, strokeWidth: 1.5 }, ref: { x: 12, y: 10 }, scale: 0.5 }); } if (type === 'conditional-flow-marker') { var conditionalflowMarker = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(conditionalflowMarker, { d: 'M 0 10 L 8 6 L 16 10 L 8 14 Z' }); addMarker(id, { element: conditionalflowMarker, attrs: { fill: fill, stroke: stroke }, ref: { x: -1, y: 10 }, scale: 0.5 }); } if (type === 'conditional-default-flow-marker') { var conditionaldefaultflowMarker = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(conditionaldefaultflowMarker, { d: 'M 6 4 L 10 16' }); addMarker(id, { element: conditionaldefaultflowMarker, attrs: { stroke: stroke }, ref: { x: 0, y: 10 }, scale: 0.5 }); } } function drawCircle(parentGfx, width, height, offset, attrs) { if ((0, _minDash.isObject)(offset)) { attrs = offset; offset = 0; } offset = offset || 0; attrs = computeStyle(attrs, { stroke: 'black', strokeWidth: 2, fill: 'white' }); if (attrs.fill === 'none') { delete attrs.fillOpacity; } var cx = width / 2, cy = height / 2; var circle = (0, _tinySvg.create)('circle'); (0, _tinySvg.attr)(circle, { cx: cx, cy: cy, r: Math.round((width + height) / 4 - offset) }); (0, _tinySvg.attr)(circle, attrs); (0, _tinySvg.append)(parentGfx, circle); return circle; } function drawRect(parentGfx, width, height, r, offset, attrs) { if ((0, _minDash.isObject)(offset)) { attrs = offset; offset = 0; } offset = offset || 0; attrs = computeStyle(attrs, { stroke: 'black', strokeWidth: 2, fill: 'white' }); var rect = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(rect, { x: offset, y: offset, width: width - offset * 2, height: height - offset * 2, rx: r, ry: r }); (0, _tinySvg.attr)(rect, attrs); (0, _tinySvg.append)(parentGfx, rect); return rect; } function drawDiamond(parentGfx, width, height, attrs) { var x_2 = width / 2; var y_2 = height / 2; var points = [{ x: x_2, y: 0 }, { x: width, y: y_2 }, { x: x_2, y: height }, { x: 0, y: y_2 }]; var pointsString = points.map(function (point) { return point.x + ',' + point.y; }).join(' '); attrs = computeStyle(attrs, { stroke: 'black', strokeWidth: 2, fill: 'white' }); var polygon = (0, _tinySvg.create)('polygon'); (0, _tinySvg.attr)(polygon, { points: pointsString }); (0, _tinySvg.attr)(polygon, attrs); (0, _tinySvg.append)(parentGfx, polygon); return polygon; } function drawLine(parentGfx, waypoints, attrs) { attrs = computeStyle(attrs, ['no-fill'], { stroke: 'black', strokeWidth: 2, fill: 'none' }); var line = (0, _RenderUtil.createLine)(waypoints, attrs); (0, _tinySvg.append)(parentGfx, line); return line; } function drawPath(parentGfx, d, attrs) { attrs = computeStyle(attrs, ['no-fill'], { strokeWidth: 2, stroke: 'black' }); var path = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(path, { d: d }); (0, _tinySvg.attr)(path, attrs); (0, _tinySvg.append)(parentGfx, path); return path; } function drawMarker(type, parentGfx, path, attrs) { return drawPath(parentGfx, path, (0, _minDash.assign)({ 'data-marker': type }, attrs)); } function as(type) { return function (parentGfx, element) { return handlers[type](parentGfx, element); }; } function renderer(type) { return handlers[type]; } function renderEventContent(element, parentGfx) { var event = (0, _BpmnRenderUtil.getSemantic)(element); var isThrowing = (0, _BpmnRenderUtil.isThrowEvent)(event); if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:MessageEventDefinition')) { return renderer('bpmn:MessageEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:TimerEventDefinition')) { return renderer('bpmn:TimerEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:ConditionalEventDefinition')) { return renderer('bpmn:ConditionalEventDefinition')(parentGfx, element); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:SignalEventDefinition')) { return renderer('bpmn:SignalEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:CancelEventDefinition') && (0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:TerminateEventDefinition', { parallelMultiple: false })) { return renderer('bpmn:MultipleEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:CancelEventDefinition') && (0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:TerminateEventDefinition', { parallelMultiple: true })) { return renderer('bpmn:ParallelMultipleEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:EscalationEventDefinition')) { return renderer('bpmn:EscalationEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:LinkEventDefinition')) { return renderer('bpmn:LinkEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:ErrorEventDefinition')) { return renderer('bpmn:ErrorEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:CancelEventDefinition')) { return renderer('bpmn:CancelEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:CompensateEventDefinition')) { return renderer('bpmn:CompensateEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:TerminateEventDefinition')) { return renderer('bpmn:TerminateEventDefinition')(parentGfx, element, isThrowing); } return null; } function renderLabel(parentGfx, label, options) { options = (0, _minDash.assign)({ size: { width: 100 } }, options); var text = textRenderer.createText(label || '', options); (0, _tinySvg.classes)(text).add('djs-label'); (0, _tinySvg.append)(parentGfx, text); return text; } function renderEmbeddedLabel(parentGfx, element, align) { var semantic = (0, _BpmnRenderUtil.getSemantic)(element); return renderLabel(parentGfx, semantic.name, { box: element, align: align, padding: 5, style: { fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) } }); } function renderExternalLabel(parentGfx, element) { var semantic = (0, _BpmnRenderUtil.getSemantic)(element); var box = { width: 90, height: 30, x: element.width / 2 + element.x, y: element.height / 2 + element.y }; return renderLabel(parentGfx, semantic.name, { box: box, fitBox: true, style: (0, _minDash.assign)({}, textRenderer.getExternalStyle(), { fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }) }); } function renderLaneLabel(parentGfx, text, element) { var textBox = renderLabel(parentGfx, text, { box: { height: 30, width: element.height }, align: 'center-middle', style: { fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) } }); var top = -1 * element.height; (0, _SvgTransformUtil.transform)(textBox, 0, -top, 270); } function createPathFromConnection(connection) { var waypoints = connection.waypoints; var pathData = 'm ' + waypoints[0].x + ',' + waypoints[0].y; for (var i = 1; i < waypoints.length; i++) { pathData += 'L' + waypoints[i].x + ',' + waypoints[i].y + ' '; } return pathData; } var handlers = this.handlers = { 'bpmn:Event': function bpmnEvent(parentGfx, element, attrs) { if (!('fillOpacity' in attrs)) { attrs.fillOpacity = DEFAULT_FILL_OPACITY; } return drawCircle(parentGfx, element.width, element.height, attrs); }, 'bpmn:StartEvent': function bpmnStartEvent(parentGfx, element) { var attrs = { fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; var semantic = (0, _BpmnRenderUtil.getSemantic)(element); if (!semantic.isInterrupting) { attrs = { strokeDasharray: '6', strokeLinecap: 'round', fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; } var circle = renderer('bpmn:Event')(parentGfx, element, attrs); renderEventContent(element, parentGfx); return circle; }, 'bpmn:MessageEventDefinition': function bpmnMessageEventDefinition(parentGfx, element, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_MESSAGE', { xScaleFactor: 0.9, yScaleFactor: 0.9, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.235, my: 0.315 } }); var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) : (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor); var stroke = isThrowing ? (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor) : (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor); var messagePath = drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill, stroke: stroke }); return messagePath; }, 'bpmn:TimerEventDefinition': function bpmnTimerEventDefinition(parentGfx, element) { var circle = drawCircle(parentGfx, element.width, element.height, 0.2 * element.height, { strokeWidth: 2, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var pathData = pathMap.getScaledPath('EVENT_TIMER_WH', { xScaleFactor: 0.75, yScaleFactor: 0.75, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.5, my: 0.5 } }); drawPath(parentGfx, pathData, { strokeWidth: 2, strokeLinecap: 'square', stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); for (var i = 0; i < 12; i++) { var linePathData = pathMap.getScaledPath('EVENT_TIMER_LINE', { xScaleFactor: 0.75, yScaleFactor: 0.75, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.5, my: 0.5 } }); var width = element.width / 2; var height = element.height / 2; drawPath(parentGfx, linePathData, { strokeWidth: 1, strokeLinecap: 'square', transform: 'rotate(' + i * 30 + ',' + height + ',' + width + ')', stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); } return circle; }, 'bpmn:EscalationEventDefinition': function bpmnEscalationEventDefinition(parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_ESCALATION', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.5, my: 0.2 } }); var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none'; return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill, stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) }); }, 'bpmn:ConditionalEventDefinition': function bpmnConditionalEventDefinition(parentGfx, event) { var pathData = pathMap.getScaledPath('EVENT_CONDITIONAL', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.5, my: 0.222 } }); return drawPath(parentGfx, pathData, { strokeWidth: 1, stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) }); }, 'bpmn:LinkEventDefinition': function bpmnLinkEventDefinition(parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_LINK', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.57, my: 0.263 } }); var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none'; return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill, stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) }); }, 'bpmn:ErrorEventDefinition': function bpmnErrorEventDefinition(parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_ERROR', { xScaleFactor: 1.1, yScaleFactor: 1.1, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.2, my: 0.722 } }); var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none'; return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill, stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) }); }, 'bpmn:CancelEventDefinition': function bpmnCancelEventDefinition(parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_CANCEL_45', { xScaleFactor: 1.0, yScaleFactor: 1.0, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.638, my: -0.055 } }); var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none'; var path = drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill, stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) }); (0, _SvgTransformUtil.rotate)(path, 45); return path; }, 'bpmn:CompensateEventDefinition': function bpmnCompensateEventDefinition(parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_COMPENSATION', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.22, my: 0.5 } }); var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none'; return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill, stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) }); }, 'bpmn:SignalEventDefinition': function bpmnSignalEventDefinition(parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_SIGNAL', { xScaleFactor: 0.9, yScaleFactor: 0.9, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.5, my: 0.2 } }); var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none'; return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill, stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) }); }, 'bpmn:MultipleEventDefinition': function bpmnMultipleEventDefinition(parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_MULTIPLE', { xScaleFactor: 1.1, yScaleFactor: 1.1, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.222, my: 0.36 } }); var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none'; return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill }); }, 'bpmn:ParallelMultipleEventDefinition': function bpmnParallelMultipleEventDefinition(parentGfx, event) { var pathData = pathMap.getScaledPath('EVENT_PARALLEL_MULTIPLE', { xScaleFactor: 1.2, yScaleFactor: 1.2, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.458, my: 0.194 } }); return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) }); }, 'bpmn:EndEvent': function bpmnEndEvent(parentGfx, element) { var circle = renderer('bpmn:Event')(parentGfx, element, { strokeWidth: 4, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); renderEventContent(element, parentGfx, true); return circle; }, 'bpmn:TerminateEventDefinition': function bpmnTerminateEventDefinition(parentGfx, element) { var circle = drawCircle(parentGfx, element.width, element.height, 8, { strokeWidth: 4, fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return circle; }, 'bpmn:IntermediateEvent': function bpmnIntermediateEvent(parentGfx, element) { var outer = renderer('bpmn:Event')(parentGfx, element, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); /* inner */ drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, 'none'), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); renderEventContent(element, parentGfx); return outer; }, 'bpmn:IntermediateCatchEvent': as('bpmn:IntermediateEvent'), 'bpmn:IntermediateThrowEvent': as('bpmn:IntermediateEvent'), 'bpmn:Activity': function bpmnActivity(parentGfx, element, attrs) { attrs = attrs || {}; if (!('fillOpacity' in attrs)) { attrs.fillOpacity = DEFAULT_FILL_OPACITY; } return drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, attrs); }, 'bpmn:Task': function bpmnTask(parentGfx, element) { var attrs = { fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; var rect = renderer('bpmn:Activity')(parentGfx, element, attrs); renderEmbeddedLabel(parentGfx, element, 'center-middle'); attachTaskMarkers(parentGfx, element); return rect; }, 'bpmn:ServiceTask': function bpmnServiceTask(parentGfx, element) { var task = renderer('bpmn:Task')(parentGfx, element); var pathDataBG = pathMap.getScaledPath('TASK_TYPE_SERVICE', { abspos: { x: 12, y: 18 } }); /* service bg */drawPath(parentGfx, pathDataBG, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var fillPathData = pathMap.getScaledPath('TASK_TYPE_SERVICE_FILL', { abspos: { x: 17.2, y: 18 } }); /* service fill */drawPath(parentGfx, fillPathData, { strokeWidth: 0, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor) }); var pathData = pathMap.getScaledPath('TASK_TYPE_SERVICE', { abspos: { x: 17, y: 22 } }); /* service */drawPath(parentGfx, pathData, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return task; }, 'bpmn:UserTask': function bpmnUserTask(parentGfx, element) { var task = renderer('bpmn:Task')(parentGfx, element); var x = 15; var y = 12; var pathData = pathMap.getScaledPath('TASK_TYPE_USER_1', { abspos: { x: x, y: y } }); /* user path */drawPath(parentGfx, pathData, { strokeWidth: 0.5, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var pathData2 = pathMap.getScaledPath('TASK_TYPE_USER_2', { abspos: { x: x, y: y } }); /* user2 path */drawPath(parentGfx, pathData2, { strokeWidth: 0.5, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var pathData3 = pathMap.getScaledPath('TASK_TYPE_USER_3', { abspos: { x: x, y: y } }); /* user3 path */drawPath(parentGfx, pathData3, { strokeWidth: 0.5, fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return task; }, 'bpmn:ManualTask': function bpmnManualTask(parentGfx, element) { var task = renderer('bpmn:Task')(parentGfx, element); var pathData = pathMap.getScaledPath('TASK_TYPE_MANUAL', { abspos: { x: 17, y: 15 } }); /* manual path */drawPath(parentGfx, pathData, { strokeWidth: 0.5, // 0.25, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return task; }, 'bpmn:SendTask': function bpmnSendTask(parentGfx, element) { var task = renderer('bpmn:Task')(parentGfx, element); var pathData = pathMap.getScaledPath('TASK_TYPE_SEND', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: 21, containerHeight: 14, position: { mx: 0.285, my: 0.357 } }); /* send path */drawPath(parentGfx, pathData, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), stroke: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor) }); return task; }, 'bpmn:ReceiveTask': function bpmnReceiveTask(parentGfx, element) { var semantic = (0, _BpmnRenderUtil.getSemantic)(element); var task = renderer('bpmn:Task')(parentGfx, element); var pathData; if (semantic.instantiate) { drawCircle(parentGfx, 28, 28, 20 * 0.22, { strokeWidth: 1 }); pathData = pathMap.getScaledPath('TASK_TYPE_INSTANTIATING_SEND', { abspos: { x: 7.77, y: 9.52 } }); } else { pathData = pathMap.getScaledPath('TASK_TYPE_SEND', { xScaleFactor: 0.9, yScaleFactor: 0.9, containerWidth: 21, containerHeight: 14, position: { mx: 0.3, my: 0.4 } }); } /* receive path */drawPath(parentGfx, pathData, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return task; }, 'bpmn:ScriptTask': function bpmnScriptTask(parentGfx, element) { var task = renderer('bpmn:Task')(parentGfx, element); var pathData = pathMap.getScaledPath('TASK_TYPE_SCRIPT', { abspos: { x: 15, y: 20 } }); /* script path */drawPath(parentGfx, pathData, { strokeWidth: 1, stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return task; }, 'bpmn:BusinessRuleTask': function bpmnBusinessRuleTask(parentGfx, element) { var task = renderer('bpmn:Task')(parentGfx, element); var headerPathData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_HEADER', { abspos: { x: 8, y: 8 } }); var businessHeaderPath = drawPath(parentGfx, headerPathData); (0, _tinySvg.attr)(businessHeaderPath, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, '#aaaaaa'), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var headerData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_MAIN', { abspos: { x: 8, y: 8 } }); var businessPath = drawPath(parentGfx, headerData); (0, _tinySvg.attr)(businessPath, { strokeWidth: 1, stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return task; }, 'bpmn:SubProcess': function bpmnSubProcess(parentGfx, element, attrs) { attrs = (0, _minDash.assign)({ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }, attrs); var rect = renderer('bpmn:Activity')(parentGfx, element, attrs); var expanded = (0, _DiUtil.isExpanded)(element); if ((0, _DiUtil.isEventSubProcess)(element)) { (0, _tinySvg.attr)(rect, { strokeDasharray: '1,2' }); } renderEmbeddedLabel(parentGfx, element, expanded ? 'center-top' : 'center-middle'); if (expanded) { attachTaskMarkers(parentGfx, element); } else { attachTaskMarkers(parentGfx, element, ['SubProcessMarker']); } return rect; }, 'bpmn:AdHocSubProcess': function bpmnAdHocSubProcess(parentGfx, element) { return renderer('bpmn:SubProcess')(parentGfx, element); }, 'bpmn:Transaction': function bpmnTransaction(parentGfx, element) { var outer = renderer('bpmn:SubProcess')(parentGfx, element); var innerAttrs = styles.style(['no-fill', 'no-events'], { stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); /* inner path */drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS - 2, INNER_OUTER_DIST, innerAttrs); return outer; }, 'bpmn:CallActivity': function bpmnCallActivity(parentGfx, element) { return renderer('bpmn:SubProcess')(parentGfx, element, { strokeWidth: 5 }); }, 'bpmn:Participant': function bpmnParticipant(parentGfx, element) { var attrs = { fillOpacity: DEFAULT_FILL_OPACITY, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; var lane = renderer('bpmn:Lane')(parentGfx, element, attrs); var expandedPool = (0, _DiUtil.isExpanded)(element); if (expandedPool) { drawLine(parentGfx, [{ x: 30, y: 0 }, { x: 30, y: element.height }], { stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var text = (0, _BpmnRenderUtil.getSemantic)(element).name; renderLaneLabel(parentGfx, text, element); } else { // Collapsed pool draw text inline var text2 = (0, _BpmnRenderUtil.getSemantic)(element).name; renderLabel(parentGfx, text2, { box: element, align: 'center-middle', style: { fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) } }); } var participantMultiplicity = !!(0, _BpmnRenderUtil.getSemantic)(element).participantMultiplicity; if (participantMultiplicity) { renderer('ParticipantMultiplicityMarker')(parentGfx, element); } return lane; }, 'bpmn:Lane': function bpmnLane(parentGfx, element, attrs) { var rect = drawRect(parentGfx, element.width, element.height, 0, (0, _minDash.assign)({ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), fillOpacity: HIGH_FILL_OPACITY, stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }, attrs)); var semantic = (0, _BpmnRenderUtil.getSemantic)(element); if (semantic.$type === 'bpmn:Lane') { var text = semantic.name; renderLaneLabel(parentGfx, text, element); } return rect; }, 'bpmn:InclusiveGateway': function bpmnInclusiveGateway(parentGfx, element) { var diamond = renderer('bpmn:Gateway')(parentGfx, element); /* circle path */ drawCircle(parentGfx, element.width, element.height, element.height * 0.24, { strokeWidth: 2.5, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return diamond; }, 'bpmn:ExclusiveGateway': function bpmnExclusiveGateway(parentGfx, element) { var diamond = renderer('bpmn:Gateway')(parentGfx, element); var pathData = pathMap.getScaledPath('GATEWAY_EXCLUSIVE', { xScaleFactor: 0.4, yScaleFactor: 0.4, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.32, my: 0.3 } }); if ((0, _BpmnRenderUtil.getDi)(element).isMarkerVisible) { drawPath(parentGfx, pathData, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); } return diamond; }, 'bpmn:ComplexGateway': function bpmnComplexGateway(parentGfx, element) { var diamond = renderer('bpmn:Gateway')(parentGfx, element); var pathData = pathMap.getScaledPath('GATEWAY_COMPLEX', { xScaleFactor: 0.5, yScaleFactor: 0.5, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.46, my: 0.26 } }); /* complex path */drawPath(parentGfx, pathData, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return diamond; }, 'bpmn:ParallelGateway': function bpmnParallelGateway(parentGfx, element) { var diamond = renderer('bpmn:Gateway')(parentGfx, element); var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', { xScaleFactor: 0.6, yScaleFactor: 0.6, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.46, my: 0.2 } }); /* parallel path */drawPath(parentGfx, pathData, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return diamond; }, 'bpmn:EventBasedGateway': function bpmnEventBasedGateway(parentGfx, element) { var semantic = (0, _BpmnRenderUtil.getSemantic)(element); var diamond = renderer('bpmn:Gateway')(parentGfx, element); /* outer circle path */drawCircle(parentGfx, element.width, element.height, element.height * 0.20, { strokeWidth: 1, fill: 'none', stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var type = semantic.eventGatewayType; var instantiate = !!semantic.instantiate; function drawEvent() { var pathData = pathMap.getScaledPath('GATEWAY_EVENT_BASED', { xScaleFactor: 0.18, yScaleFactor: 0.18, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.36, my: 0.44 } }); var attrs = { strokeWidth: 2, fill: (0, _BpmnRenderUtil.getFillColor)(element, 'none'), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; /* event path */drawPath(parentGfx, pathData, attrs); } if (type === 'Parallel') { var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', { xScaleFactor: 0.4, yScaleFactor: 0.4, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.474, my: 0.296 } }); var parallelPath = drawPath(parentGfx, pathData); (0, _tinySvg.attr)(parallelPath, { strokeWidth: 1, fill: 'none' }); } else if (type === 'Exclusive') { if (!instantiate) { var innerCircle = drawCircle(parentGfx, element.width, element.height, element.height * 0.26); (0, _tinySvg.attr)(innerCircle, { strokeWidth: 1, fill: 'none', stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); } drawEvent(); } return diamond; }, 'bpmn:Gateway': function bpmnGateway(parentGfx, element) { var attrs = { fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), fillOpacity: DEFAULT_FILL_OPACITY, stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; return drawDiamond(parentGfx, element.width, element.height, attrs); }, 'bpmn:SequenceFlow': function bpmnSequenceFlow(parentGfx, element) { var pathData = createPathFromConnection(element); var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor); var attrs = { strokeLinejoin: 'round', markerEnd: marker('sequenceflow-end', fill, stroke), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; var path = drawPath(parentGfx, pathData, attrs); var sequenceFlow = (0, _BpmnRenderUtil.getSemantic)(element); var source; if (element.source) { source = element.source.businessObject; // conditional flow marker if (sequenceFlow.conditionExpression && source.$instanceOf('bpmn:Activity')) { (0, _tinySvg.attr)(path, { markerStart: marker('conditional-flow-marker', fill, stroke) }); } // default marker if (source.default && (source.$instanceOf('bpmn:Gateway') || source.$instanceOf('bpmn:Activity')) && source.default === sequenceFlow) { (0, _tinySvg.attr)(path, { markerStart: marker('conditional-default-flow-marker', fill, stroke) }); } } return path; }, 'bpmn:Association': function bpmnAssociation(parentGfx, element, attrs) { var semantic = (0, _BpmnRenderUtil.getSemantic)(element); var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor); attrs = (0, _minDash.assign)({ strokeDasharray: '0.5, 5', strokeLinecap: 'round', strokeLinejoin: 'round', stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }, attrs || {}); if (semantic.associationDirection === 'One' || semantic.associationDirection === 'Both') { attrs.markerEnd = marker('association-end', fill, stroke); } if (semantic.associationDirection === 'Both') { attrs.markerStart = marker('association-start', fill, stroke); } return drawLine(parentGfx, element.waypoints, attrs); }, 'bpmn:DataInputAssociation': function bpmnDataInputAssociation(parentGfx, element) { var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor); return renderer('bpmn:Association')(parentGfx, element, { markerEnd: marker('association-end', fill, stroke) }); }, 'bpmn:DataOutputAssociation': function bpmnDataOutputAssociation(parentGfx, element) { var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor); return renderer('bpmn:Association')(parentGfx, element, { markerEnd: marker('association-end', fill, stroke) }); }, 'bpmn:MessageFlow': function bpmnMessageFlow(parentGfx, element) { var semantic = (0, _BpmnRenderUtil.getSemantic)(element), di = (0, _BpmnRenderUtil.getDi)(element); var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor); var pathData = createPathFromConnection(element); var attrs = { markerEnd: marker('messageflow-end', fill, stroke), markerStart: marker('messageflow-start', fill, stroke), strokeDasharray: '10, 12', strokeLinecap: 'round', strokeLinejoin: 'round', strokeWidth: '1.5px', stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; var path = drawPath(parentGfx, pathData, attrs); if (semantic.messageRef) { var midPoint = path.getPointAtLength(path.getTotalLength() / 2); var markerPathData = pathMap.getScaledPath('MESSAGE_FLOW_MARKER', { abspos: { x: midPoint.x, y: midPoint.y } }); var messageAttrs = { strokeWidth: 1 }; if (di.messageVisibleKind === 'initiating') { messageAttrs.fill = 'white'; messageAttrs.stroke = 'black'; } else { messageAttrs.fill = '#888'; messageAttrs.stroke = 'white'; } drawPath(parentGfx, markerPathData, messageAttrs); } return path; }, 'bpmn:DataObject': function bpmnDataObject(parentGfx, element) { var pathData = pathMap.getScaledPath('DATA_OBJECT_PATH', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.474, my: 0.296 } }); var elementObject = drawPath(parentGfx, pathData, { fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), fillOpacity: DEFAULT_FILL_OPACITY, stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var semantic = (0, _BpmnRenderUtil.getSemantic)(element); if ((0, _BpmnRenderUtil.isCollection)(semantic)) { renderDataItemCollection(parentGfx, element); } return elementObject; }, 'bpmn:DataObjectReference': as('bpmn:DataObject'), 'bpmn:DataInput': function bpmnDataInput(parentGfx, element) { var arrowPathData = pathMap.getRawPath('DATA_ARROW'); // page var elementObject = renderer('bpmn:DataObject')(parentGfx, element); /* input arrow path */drawPath(parentGfx, arrowPathData, { strokeWidth: 1 }); return elementObject; }, 'bpmn:DataOutput': function bpmnDataOutput(parentGfx, element) { var arrowPathData = pathMap.getRawPath('DATA_ARROW'); // page var elementObject = renderer('bpmn:DataObject')(parentGfx, element); /* output arrow path */drawPath(parentGfx, arrowPathData, { strokeWidth: 1, fill: 'black' }); return elementObject; }, 'bpmn:DataStoreReference': function bpmnDataStoreReference(parentGfx, element) { var DATA_STORE_PATH = pathMap.getScaledPath('DATA_STORE', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: 0, my: 0.133 } }); var elementStore = drawPath(parentGfx, DATA_STORE_PATH, { strokeWidth: 2, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), fillOpacity: DEFAULT_FILL_OPACITY, stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return elementStore; }, 'bpmn:BoundaryEvent': function bpmnBoundaryEvent(parentGfx, element) { var semantic = (0, _BpmnRenderUtil.getSemantic)(element), cancel = semantic.cancelActivity; var attrs = { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; if (!cancel) { attrs.strokeDasharray = '6'; attrs.strokeLinecap = 'round'; } // apply fillOpacity var outerAttrs = (0, _minDash.assign)({}, attrs, { fillOpacity: 1 }); // apply no-fill var innerAttrs = (0, _minDash.assign)({}, attrs, { fill: 'none' }); var outer = renderer('bpmn:Event')(parentGfx, element, outerAttrs); /* inner path */drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, innerAttrs); renderEventContent(element, parentGfx); return outer; }, 'bpmn:Group': function bpmnGroup(parentGfx, element) { var semantic = (0, _BpmnRenderUtil.getSemantic)(element), di = (0, _BpmnRenderUtil.getDi)(element); var group = drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, { strokeWidth: 1, strokeDasharray: '8,3,1,3', fill: 'none', pointerEvents: 'none' }); var categoryValueRef = semantic.categoryValueRef || {}; if (categoryValueRef.value) { var box = di.label ? di.label.bounds : element; renderLabel(parentGfx, categoryValueRef.value, { box: box, style: { fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) } }); } return group; }, 'label': function label(parentGfx, element) { return renderExternalLabel(parentGfx, element); }, 'bpmn:TextAnnotation': function bpmnTextAnnotation(parentGfx, element) { var style = { 'fill': 'none', 'stroke': 'none' }; var textElement = drawRect(parentGfx, element.width, element.height, 0, 0, style); var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.0, my: 0.0 } }); drawPath(parentGfx, textPathData, { stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var text = (0, _BpmnRenderUtil.getSemantic)(element).text || ''; renderLabel(parentGfx, text, { box: element, align: 'left-top', padding: 5, style: { fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) } }); return textElement; }, 'ParticipantMultiplicityMarker': function ParticipantMultiplicityMarker(parentGfx, element) { var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: element.width / 2 / element.width, my: (element.height - 15) / element.height } }); drawMarker('participant-multiplicity', parentGfx, markerPath, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); }, 'SubProcessMarker': function SubProcessMarker(parentGfx, element) { var markerRect = drawRect(parentGfx, 14, 14, 0, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); // Process marker is placed in the middle of the box // therefore fixed values can be used here (0, _SvgTransformUtil.translate)(markerRect, element.width / 2 - 7.5, element.height - 20); var markerPath = pathMap.getScaledPath('MARKER_SUB_PROCESS', { xScaleFactor: 1.5, yScaleFactor: 1.5, containerWidth: element.width, containerHeight: element.height, position: { mx: (element.width / 2 - 7.5) / element.width, my: (element.height - 20) / element.height } }); drawMarker('sub-process', parentGfx, markerPath, { fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); }, 'ParallelMarker': function ParallelMarker(parentGfx, element, position) { var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: (element.width / 2 + position.parallel) / element.width, my: (element.height - 20) / element.height } }); drawMarker('parallel', parentGfx, markerPath, { fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); }, 'SequentialMarker': function SequentialMarker(parentGfx, element, position) { var markerPath = pathMap.getScaledPath('MARKER_SEQUENTIAL', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: (element.width / 2 + position.seq) / element.width, my: (element.height - 19) / element.height } }); drawMarker('sequential', parentGfx, markerPath, { fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); }, 'CompensationMarker': function CompensationMarker(parentGfx, element, position) { var markerMath = pathMap.getScaledPath('MARKER_COMPENSATION', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: (element.width / 2 + position.compensation) / element.width, my: (element.height - 13) / element.height } }); drawMarker('compensation', parentGfx, markerMath, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); }, 'LoopMarker': function LoopMarker(parentGfx, element, position) { var markerPath = pathMap.getScaledPath('MARKER_LOOP', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: (element.width / 2 + position.loop) / element.width, my: (element.height - 7) / element.height } }); drawMarker('loop', parentGfx, markerPath, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), strokeLinecap: 'round', strokeMiterlimit: 0.5 }); }, 'AdhocMarker': function AdhocMarker(parentGfx, element, position) { var markerPath = pathMap.getScaledPath('MARKER_ADHOC', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: (element.width / 2 + position.adhoc) / element.width, my: (element.height - 15) / element.height } }); drawMarker('adhoc', parentGfx, markerPath, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); } }; function attachTaskMarkers(parentGfx, element, taskMarkers) { var obj = (0, _BpmnRenderUtil.getSemantic)(element); var subprocess = taskMarkers && taskMarkers.indexOf('SubProcessMarker') !== -1; var position; if (subprocess) { position = { seq: -21, parallel: -22, compensation: -42, loop: -18, adhoc: 10 }; } else { position = { seq: -3, parallel: -6, compensation: -27, loop: 0, adhoc: 10 }; } (0, _minDash.forEach)(taskMarkers, function (marker) { renderer(marker)(parentGfx, element, position); }); if (obj.isForCompensation) { renderer('CompensationMarker')(parentGfx, element, position); } if (obj.$type === 'bpmn:AdHocSubProcess') { renderer('AdhocMarker')(parentGfx, element, position); } var loopCharacteristics = obj.loopCharacteristics, isSequential = loopCharacteristics && loopCharacteristics.isSequential; if (loopCharacteristics) { if (isSequential === undefined) { renderer('LoopMarker')(parentGfx, element, position); } if (isSequential === false) { renderer('ParallelMarker')(parentGfx, element, position); } if (isSequential === true) { renderer('SequentialMarker')(parentGfx, element, position); } } } function renderDataItemCollection(parentGfx, element) { var yPosition = (element.height - 16) / element.height; var pathData = pathMap.getScaledPath('DATA_OBJECT_COLLECTION_PATH', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.451, my: yPosition } }); /* collection path */drawPath(parentGfx, pathData, { strokeWidth: 2 }); } // extension API, use at your own risk this._drawPath = drawPath; } (0, _inherits2.default)(BpmnRenderer, _BaseRenderer2.default); BpmnRenderer.$inject = ['config.bpmnRenderer', 'eventBus', 'styles', 'pathMap', 'canvas', 'textRenderer']; BpmnRenderer.prototype.canRender = function (element) { return (0, _ModelUtil.is)(element, 'bpmn:BaseElement'); }; BpmnRenderer.prototype.drawShape = function (parentGfx, element) { var type = element.type; var h = this.handlers[type]; /* jshint -W040 */ return h(parentGfx, element); }; BpmnRenderer.prototype.drawConnection = function (parentGfx, element) { var type = element.type; var h = this.handlers[type]; /* jshint -W040 */ return h(parentGfx, element); }; BpmnRenderer.prototype.getShapePath = function (element) { if ((0, _ModelUtil.is)(element, 'bpmn:Event')) { return (0, _BpmnRenderUtil.getCirclePath)(element); } if ((0, _ModelUtil.is)(element, 'bpmn:Activity')) { return (0, _BpmnRenderUtil.getRoundRectPath)(element, TASK_BORDER_RADIUS); } if ((0, _ModelUtil.is)(element, 'bpmn:Gateway')) { return (0, _BpmnRenderUtil.getDiamondPath)(element); } return (0, _BpmnRenderUtil.getRectPath)(element); }; },{"../util/DiUtil":214,"../util/ModelUtil":216,"./BpmnRenderUtil":118,"diagram-js/lib/draw/BaseRenderer":252,"diagram-js/lib/util/RenderUtil":407,"diagram-js/lib/util/SvgTransformUtil":408,"ids":414,"inherits":415,"min-dash":505,"min-dom":506,"tiny-svg":535}],120:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = PathMap; /** * Map containing SVG paths needed by BpmnRenderer. */ function PathMap() { /** * Contains a map of path elements * *

Path definition

* A parameterized path is defined like this: *
   * 'GATEWAY_PARALLEL': {
   *   d: 'm {mx},{my} {e.x0},0 0,{e.x1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' +
          '-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z',
   *   height: 17.5,
   *   width:  17.5,
   *   heightElements: [2.5, 7.5],
   *   widthElements: [2.5, 7.5]
   * }
   * 
*

It's important to specify a correct height and width for the path as the scaling * is based on the ratio between the specified height and width in this object and the * height and width that is set as scale target (Note x,y coordinates will be scaled with * individual ratios).

*

The 'heightElements' and 'widthElements' array must contain the values that will be scaled. * The scaling is based on the computed ratios. * Coordinates on the y axis should be in the heightElement's array, they will be scaled using * the computed ratio coefficient. * In the parameterized path the scaled values can be accessed through the 'e' object in {} brackets. *

    *
  • The values for the y axis can be accessed in the path string using {e.y0}, {e.y1}, ....
  • *
  • The values for the x axis can be accessed in the path string using {e.x0}, {e.x1}, ....
  • *
* The numbers x0, x1 respectively y0, y1, ... map to the corresponding array index. *

*/ this.pathMap = { 'EVENT_MESSAGE': { d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}', height: 36, width: 36, heightElements: [6, 14], widthElements: [10.5, 21] }, 'EVENT_SIGNAL': { d: 'M {mx},{my} l {e.x0},{e.y0} l -{e.x1},0 Z', height: 36, width: 36, heightElements: [18], widthElements: [10, 20] }, 'EVENT_ESCALATION': { d: 'M {mx},{my} l {e.x0},{e.y0} l -{e.x0},-{e.y1} l -{e.x0},{e.y1} Z', height: 36, width: 36, heightElements: [20, 7], widthElements: [8] }, 'EVENT_CONDITIONAL': { d: 'M {e.x0},{e.y0} l {e.x1},0 l 0,{e.y2} l -{e.x1},0 Z ' + 'M {e.x2},{e.y3} l {e.x0},0 ' + 'M {e.x2},{e.y4} l {e.x0},0 ' + 'M {e.x2},{e.y5} l {e.x0},0 ' + 'M {e.x2},{e.y6} l {e.x0},0 ' + 'M {e.x2},{e.y7} l {e.x0},0 ' + 'M {e.x2},{e.y8} l {e.x0},0 ', height: 36, width: 36, heightElements: [8.5, 14.5, 18, 11.5, 14.5, 17.5, 20.5, 23.5, 26.5], widthElements: [10.5, 14.5, 12.5] }, 'EVENT_LINK': { d: 'm {mx},{my} 0,{e.y0} -{e.x1},0 0,{e.y1} {e.x1},0 0,{e.y0} {e.x0},-{e.y2} -{e.x0},-{e.y2} z', height: 36, width: 36, heightElements: [4.4375, 6.75, 7.8125], widthElements: [9.84375, 13.5] }, 'EVENT_ERROR': { d: 'm {mx},{my} {e.x0},-{e.y0} {e.x1},-{e.y1} {e.x2},{e.y2} {e.x3},-{e.y3} -{e.x4},{e.y4} -{e.x5},-{e.y5} z', height: 36, width: 36, heightElements: [0.023, 8.737, 8.151, 16.564, 10.591, 8.714], widthElements: [0.085, 6.672, 6.97, 4.273, 5.337, 6.636] }, 'EVENT_CANCEL_45': { d: 'm {mx},{my} -{e.x1},0 0,{e.x0} {e.x1},0 0,{e.y1} {e.x0},0 ' + '0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z', height: 36, width: 36, heightElements: [4.75, 8.5], widthElements: [4.75, 8.5] }, 'EVENT_COMPENSATION': { d: 'm {mx},{my} {e.x0},-{e.y0} 0,{e.y1} z m {e.x1},-{e.y2} {e.x2},-{e.y3} 0,{e.y1} -{e.x2},-{e.y3} z', height: 36, width: 36, heightElements: [6.5, 13, 0.4, 6.1], widthElements: [9, 9.3, 8.7] }, 'EVENT_TIMER_WH': { d: 'M {mx},{my} l {e.x0},-{e.y0} m -{e.x0},{e.y0} l {e.x1},{e.y1} ', height: 36, width: 36, heightElements: [10, 2], widthElements: [3, 7] }, 'EVENT_TIMER_LINE': { d: 'M {mx},{my} ' + 'm {e.x0},{e.y0} l -{e.x1},{e.y1} ', height: 36, width: 36, heightElements: [10, 3], widthElements: [0, 0] }, 'EVENT_MULTIPLE': { d: 'm {mx},{my} {e.x1},-{e.y0} {e.x1},{e.y0} -{e.x0},{e.y1} -{e.x2},0 z', height: 36, width: 36, heightElements: [6.28099, 12.56199], widthElements: [3.1405, 9.42149, 12.56198] }, 'EVENT_PARALLEL_MULTIPLE': { d: 'm {mx},{my} {e.x0},0 0,{e.y1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' + '-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z', height: 36, width: 36, heightElements: [2.56228, 7.68683], widthElements: [2.56228, 7.68683] }, 'GATEWAY_EXCLUSIVE': { d: 'm {mx},{my} {e.x0},{e.y0} {e.x1},{e.y0} {e.x2},0 {e.x4},{e.y2} ' + '{e.x4},{e.y1} {e.x2},0 {e.x1},{e.y3} {e.x0},{e.y3} ' + '{e.x3},0 {e.x5},{e.y1} {e.x5},{e.y2} {e.x3},0 z', height: 17.5, width: 17.5, heightElements: [8.5, 6.5312, -6.5312, -8.5], widthElements: [6.5, -6.5, 3, -3, 5, -5] }, 'GATEWAY_PARALLEL': { d: 'm {mx},{my} 0,{e.y1} -{e.x1},0 0,{e.y0} {e.x1},0 0,{e.y1} {e.x0},0 ' + '0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z', height: 30, width: 30, heightElements: [5, 12.5], widthElements: [5, 12.5] }, 'GATEWAY_EVENT_BASED': { d: 'm {mx},{my} {e.x0},{e.y0} {e.x0},{e.y1} {e.x1},{e.y2} {e.x2},0 z', height: 11, width: 11, heightElements: [-6, 6, 12, -12], widthElements: [9, -3, -12] }, 'GATEWAY_COMPLEX': { d: 'm {mx},{my} 0,{e.y0} -{e.x0},-{e.y1} -{e.x1},{e.y2} {e.x0},{e.y1} -{e.x2},0 0,{e.y3} ' + '{e.x2},0 -{e.x0},{e.y1} l {e.x1},{e.y2} {e.x0},-{e.y1} 0,{e.y0} {e.x3},0 0,-{e.y0} {e.x0},{e.y1} ' + '{e.x1},-{e.y2} -{e.x0},-{e.y1} {e.x2},0 0,-{e.y3} -{e.x2},0 {e.x0},-{e.y1} -{e.x1},-{e.y2} ' + '-{e.x0},{e.y1} 0,-{e.y0} -{e.x3},0 z', height: 17.125, width: 17.125, heightElements: [4.875, 3.4375, 2.125, 3], widthElements: [3.4375, 2.125, 4.875, 3] }, 'DATA_OBJECT_PATH': { d: 'm 0,0 {e.x1},0 {e.x0},{e.y0} 0,{e.y1} -{e.x2},0 0,-{e.y2} {e.x1},0 0,{e.y0} {e.x0},0', height: 61, width: 51, heightElements: [10, 50, 60], widthElements: [10, 40, 50, 60] }, 'DATA_OBJECT_COLLECTION_PATH': { d: 'm {mx}, {my} ' + 'm 0 15 l 0 -15 ' + 'm 4 15 l 0 -15 ' + 'm 4 15 l 0 -15 ', height: 61, width: 51, heightElements: [12], widthElements: [1, 6, 12, 15] }, 'DATA_ARROW': { d: 'm 5,9 9,0 0,-3 5,5 -5,5 0,-3 -9,0 z', height: 61, width: 51, heightElements: [], widthElements: [] }, 'DATA_STORE': { d: 'm {mx},{my} ' + 'l 0,{e.y2} ' + 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0 ' + 'l 0,-{e.y2} ' + 'c -{e.x0},-{e.y1} -{e.x1},-{e.y1} -{e.x2},0' + 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0 ' + 'm -{e.x2},{e.y0}' + 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0' + 'm -{e.x2},{e.y0}' + 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0', height: 61, width: 61, heightElements: [7, 10, 45], widthElements: [2, 58, 60] }, 'TEXT_ANNOTATION': { d: 'm {mx}, {my} m 10,0 l -10,0 l 0,{e.y0} l 10,0', height: 30, width: 10, heightElements: [30], widthElements: [10] }, 'MARKER_SUB_PROCESS': { d: 'm{mx},{my} m 7,2 l 0,10 m -5,-5 l 10,0', height: 10, width: 10, heightElements: [], widthElements: [] }, 'MARKER_PARALLEL': { d: 'm{mx},{my} m 3,2 l 0,10 m 3,-10 l 0,10 m 3,-10 l 0,10', height: 10, width: 10, heightElements: [], widthElements: [] }, 'MARKER_SEQUENTIAL': { d: 'm{mx},{my} m 0,3 l 10,0 m -10,3 l 10,0 m -10,3 l 10,0', height: 10, width: 10, heightElements: [], widthElements: [] }, 'MARKER_COMPENSATION': { d: 'm {mx},{my} 7,-5 0,10 z m 7.1,-0.3 6.9,-4.7 0,10 -6.9,-4.7 z', height: 10, width: 21, heightElements: [], widthElements: [] }, 'MARKER_LOOP': { d: 'm {mx},{my} c 3.526979,0 6.386161,-2.829858 6.386161,-6.320661 0,-3.490806 -2.859182,-6.320661 ' + '-6.386161,-6.320661 -3.526978,0 -6.38616,2.829855 -6.38616,6.320661 0,1.745402 ' + '0.714797,3.325567 1.870463,4.469381 0.577834,0.571908 1.265885,1.034728 2.029916,1.35457 ' + 'l -0.718163,-3.909793 m 0.718163,3.909793 -3.885211,0.802902', height: 13.9, width: 13.7, heightElements: [], widthElements: [] }, 'MARKER_ADHOC': { d: 'm {mx},{my} m 0.84461,2.64411 c 1.05533,-1.23780996 2.64337,-2.07882 4.29653,-1.97997996 2.05163,0.0805 ' + '3.85579,1.15803 5.76082,1.79107 1.06385,0.34139996 2.24454,0.1438 3.18759,-0.43767 0.61743,-0.33642 ' + '1.2775,-0.64078 1.7542,-1.17511 0,0.56023 0,1.12046 0,1.6807 -0.98706,0.96237996 -2.29792,1.62393996 ' + '-3.6918,1.66181996 -1.24459,0.0927 -2.46671,-0.2491 -3.59505,-0.74812 -1.35789,-0.55965 ' + '-2.75133,-1.33436996 -4.27027,-1.18121996 -1.37741,0.14601 -2.41842,1.13685996 -3.44288,1.96782996 z', height: 4, width: 15, heightElements: [], widthElements: [] }, 'TASK_TYPE_SEND': { d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}', height: 14, width: 21, heightElements: [6, 14], widthElements: [10.5, 21] }, 'TASK_TYPE_SCRIPT': { d: 'm {mx},{my} c 9.966553,-6.27276 -8.000926,-7.91932 2.968968,-14.938 l -8.802728,0 ' + 'c -10.969894,7.01868 6.997585,8.66524 -2.968967,14.938 z ' + 'm -7,-12 l 5,0 ' + 'm -4.5,3 l 4.5,0 ' + 'm -3,3 l 5,0' + 'm -4,3 l 5,0', height: 15, width: 12.6, heightElements: [6, 14], widthElements: [10.5, 21] }, 'TASK_TYPE_USER_1': { d: 'm {mx},{my} c 0.909,-0.845 1.594,-2.049 1.594,-3.385 0,-2.554 -1.805,-4.62199999 ' + '-4.357,-4.62199999 -2.55199998,0 -4.28799998,2.06799999 -4.28799998,4.62199999 0,1.348 ' + '0.974,2.562 1.89599998,3.405 -0.52899998,0.187 -5.669,2.097 -5.794,4.7560005 v 6.718 ' + 'h 17 v -6.718 c 0,-2.2980005 -5.5279996,-4.5950005 -6.0509996,-4.7760005 z' + 'm -8,6 l 0,5.5 m 11,0 l 0,-5' }, 'TASK_TYPE_USER_2': { d: 'm {mx},{my} m 2.162,1.009 c 0,2.4470005 -2.158,4.4310005 -4.821,4.4310005 ' + '-2.66499998,0 -4.822,-1.981 -4.822,-4.4310005 ' }, 'TASK_TYPE_USER_3': { d: 'm {mx},{my} m -6.9,-3.80 c 0,0 2.25099998,-2.358 4.27399998,-1.177 2.024,1.181 4.221,1.537 ' + '4.124,0.965 -0.098,-0.57 -0.117,-3.79099999 -4.191,-4.13599999 -3.57499998,0.001 ' + '-4.20799998,3.36699999 -4.20699998,4.34799999 z' }, 'TASK_TYPE_MANUAL': { d: 'm {mx},{my} c 0.234,-0.01 5.604,0.008 8.029,0.004 0.808,0 1.271,-0.172 1.417,-0.752 0.227,-0.898 ' + '-0.334,-1.314 -1.338,-1.316 -2.467,-0.01 -7.886,-0.004 -8.108,-0.004 -0.014,-0.079 0.016,-0.533 0,-0.61 ' + '0.195,-0.042 8.507,0.006 9.616,0.002 0.877,-0.007 1.35,-0.438 1.353,-1.208 0.003,-0.768 -0.479,-1.09 ' + '-1.35,-1.091 -2.968,-0.002 -9.619,-0.013 -9.619,-0.013 v -0.591 c 0,0 5.052,-0.016 7.225,-0.016 ' + '0.888,-0.002 1.354,-0.416 1.351,-1.193 -0.006,-0.761 -0.492,-1.196 -1.361,-1.196 -3.473,-0.005 ' + '-10.86,-0.003 -11.0829995,-0.003 -0.022,-0.047 -0.045,-0.094 -0.069,-0.139 0.3939995,-0.319 ' + '2.0409995,-1.626 2.4149995,-2.017 0.469,-0.4870005 0.519,-1.1650005 0.162,-1.6040005 -0.414,-0.511 ' + '-0.973,-0.5 -1.48,-0.236 -1.4609995,0.764 -6.5999995,3.6430005 -7.7329995,4.2710005 -0.9,0.499 ' + '-1.516,1.253 -1.882,2.19 -0.37000002,0.95 -0.17,2.01 -0.166,2.979 0.004,0.718 -0.27300002,1.345 ' + '-0.055,2.063 0.629,2.087 2.425,3.312 4.859,3.318 4.6179995,0.014 9.2379995,-0.139 13.8569995,-0.158 ' + '0.755,-0.004 1.171,-0.301 1.182,-1.033 0.012,-0.754 -0.423,-0.969 -1.183,-0.973 -1.778,-0.01 ' + '-5.824,-0.004 -6.04,-0.004 10e-4,-0.084 0.003,-0.586 10e-4,-0.67 z' }, 'TASK_TYPE_INSTANTIATING_SEND': { d: 'm {mx},{my} l 0,8.4 l 12.6,0 l 0,-8.4 z l 6.3,3.6 l 6.3,-3.6' }, 'TASK_TYPE_SERVICE': { d: 'm {mx},{my} v -1.71335 c 0.352326,-0.0705 0.703932,-0.17838 1.047628,-0.32133 ' + '0.344416,-0.14465 0.665822,-0.32133 0.966377,-0.52145 l 1.19431,1.18005 1.567487,-1.57688 ' + '-1.195028,-1.18014 c 0.403376,-0.61394 0.683079,-1.29908 0.825447,-2.01824 l 1.622133,-0.01 ' + 'v -2.2196 l -1.636514,0.01 c -0.07333,-0.35153 -0.178319,-0.70024 -0.323564,-1.04372 ' + '-0.145244,-0.34406 -0.321407,-0.6644 -0.522735,-0.96217 l 1.131035,-1.13631 -1.583305,-1.56293 ' + '-1.129598,1.13589 c -0.614052,-0.40108 -1.302883,-0.68093 -2.022633,-0.82247 l 0.0093,-1.61852 ' + 'h -2.241173 l 0.0042,1.63124 c -0.353763,0.0736 -0.705369,0.17977 -1.049785,0.32371 -0.344415,0.14437 ' + '-0.665102,0.32092 -0.9635006,0.52046 l -1.1698628,-1.15823 -1.5667691,1.5792 1.1684265,1.15669 ' + 'c -0.4026573,0.61283 -0.68308,1.29797 -0.8247287,2.01713 l -1.6588041,0.003 v 2.22174 ' + 'l 1.6724648,-0.006 c 0.073327,0.35077 0.1797598,0.70243 0.3242851,1.04472 0.1452428,0.34448 ' + '0.3214064,0.6644 0.5227339,0.96066 l -1.1993431,1.19723 1.5840256,1.56011 1.1964668,-1.19348 ' + 'c 0.6140517,0.40346 1.3028827,0.68232 2.0233517,0.82331 l 7.19e-4,1.69892 h 2.226848 z ' + 'm 0.221462,-3.9957 c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' + '0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' + '0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 z' }, 'TASK_TYPE_SERVICE_FILL': { d: 'm {mx},{my} c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' + '0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' + '0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 z' }, 'TASK_TYPE_BUSINESS_RULE_HEADER': { d: 'm {mx},{my} 0,4 20,0 0,-4 z' }, 'TASK_TYPE_BUSINESS_RULE_MAIN': { d: 'm {mx},{my} 0,12 20,0 0,-12 z' + 'm 0,8 l 20,0 ' + 'm -13,-4 l 0,8' }, 'MESSAGE_FLOW_MARKER': { d: 'm {mx},{my} m -10.5 ,-7 l 0,14 l 21,0 l 0,-14 z l 10.5,6 l 10.5,-6' } }; this.getRawPath = function getRawPath(pathId) { return this.pathMap[pathId].d; }; /** * Scales the path to the given height and width. *

Use case

*

Use case is to scale the content of elements (event, gateways) based * on the element bounding box's size. *

*

Why not transform

*

Scaling a path with transform() will also scale the stroke and IE does not support * the option 'non-scaling-stroke' to prevent this. * Also there are use cases where only some parts of a path should be * scaled.

* * @param {String} pathId The ID of the path. * @param {Object} param

* Example param object scales the path to 60% size of the container (data.width, data.height). *

   *   {
   *     xScaleFactor: 0.6,
   *     yScaleFactor:0.6,
   *     containerWidth: data.width,
   *     containerHeight: data.height,
   *     position: {
   *       mx: 0.46,
   *       my: 0.2,
   *     }
   *   }
   *   
*
    *
  • targetpathwidth = xScaleFactor * containerWidth
  • *
  • targetpathheight = yScaleFactor * containerHeight
  • *
  • Position is used to set the starting coordinate of the path. M is computed: *
      *
    • position.x * containerWidth
    • *
    • position.y * containerHeight
    • *
    * Center of the container
     position: {
       *       mx: 0.5,
       *       my: 0.5,
       *     }
    * Upper left corner of the container *
     position: {
       *       mx: 0.0,
       *       my: 0.0,
       *     }
    *
  • *
*

* */ this.getScaledPath = function getScaledPath(pathId, param) { var rawPath = this.pathMap[pathId]; // positioning // compute the start point of the path var mx, my; if (param.abspos) { mx = param.abspos.x; my = param.abspos.y; } else { mx = param.containerWidth * param.position.mx; my = param.containerHeight * param.position.my; } var coordinates = {}; // map for the scaled coordinates if (param.position) { // path var heightRatio = param.containerHeight / rawPath.height * param.yScaleFactor; var widthRatio = param.containerWidth / rawPath.width * param.xScaleFactor; // Apply height ratio for (var heightIndex = 0; heightIndex < rawPath.heightElements.length; heightIndex++) { coordinates['y' + heightIndex] = rawPath.heightElements[heightIndex] * heightRatio; } // Apply width ratio for (var widthIndex = 0; widthIndex < rawPath.widthElements.length; widthIndex++) { coordinates['x' + widthIndex] = rawPath.widthElements[widthIndex] * widthRatio; } } // Apply value to raw path var path = format(rawPath.d, { mx: mx, my: my, e: coordinates }); return path; }; } // helpers ////////////////////// // copied from https://github.com/adobe-webplatform/Snap.svg/blob/master/src/svg.js var tokenRegex = /\{([^}]+)\}/g, objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g; // matches .xxxxx or ["xxxxx"] to run over object properties function replacer(all, key, obj) { var res = obj; key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) { name = name || quotedName; if (res) { if (name in res) { res = res[name]; } typeof res == 'function' && isFunc && (res = res()); } }); res = (res == null || res == obj ? all : res) + ''; return res; } function format(str, obj) { return String(str).replace(tokenRegex, function (all, key) { return replacer(all, key, obj); }); } },{}],121:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = TextRenderer; var _minDash = require('min-dash'); var _Text = require('diagram-js/lib/util/Text'); var _Text2 = _interopRequireDefault(_Text); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var DEFAULT_FONT_SIZE = 12; var LINE_HEIGHT_RATIO = 1.2; var MIN_TEXT_ANNOTATION_HEIGHT = 30; function TextRenderer(config) { var defaultStyle = (0, _minDash.assign)({ fontFamily: 'Arial, sans-serif', fontSize: DEFAULT_FONT_SIZE, fontWeight: 'normal', lineHeight: LINE_HEIGHT_RATIO }, config && config.defaultStyle || {}); var fontSize = parseInt(defaultStyle.fontSize, 10) - 1; var externalStyle = (0, _minDash.assign)({}, defaultStyle, { fontSize: fontSize }, config && config.externalStyle || {}); var textUtil = new _Text2.default({ style: defaultStyle }); /** * Get the new bounds of an externally rendered, * layouted label. * * @param {Bounds} bounds * @param {String} text * * @return {Bounds} */ this.getExternalLabelBounds = function (bounds, text) { var layoutedDimensions = textUtil.getDimensions(text, { box: { width: 90, height: 30, x: bounds.width / 2 + bounds.x, y: bounds.height / 2 + bounds.y }, style: externalStyle }); // resize label shape to fit label text return { x: Math.round(bounds.x + bounds.width / 2 - layoutedDimensions.width / 2), y: Math.round(bounds.y), width: Math.ceil(layoutedDimensions.width), height: Math.ceil(layoutedDimensions.height) }; }; /** * Get the new bounds of text annotation. * * @param {Bounds} bounds * @param {String} text * * @return {Bounds} */ this.getTextAnnotationBounds = function (bounds, text) { var layoutedDimensions = textUtil.getDimensions(text, { box: bounds, style: defaultStyle, align: 'left-top', padding: 5 }); return { x: bounds.x, y: bounds.y, width: bounds.width, height: Math.max(MIN_TEXT_ANNOTATION_HEIGHT, Math.round(layoutedDimensions.height)) }; }; /** * Create a layouted text element. * * @param {String} text * @param {Object} [options] * * @return {SVGElement} rendered text */ this.createText = function (text, options) { return textUtil.createText(text, options || {}); }; /** * Get default text style. */ this.getDefaultStyle = function () { return defaultStyle; }; /** * Get the external text style. */ this.getExternalStyle = function () { return externalStyle; }; } TextRenderer.$inject = ['config.textRenderer']; },{"diagram-js/lib/util/Text":409,"min-dash":505}],122:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _BpmnRenderer = require('./BpmnRenderer'); var _BpmnRenderer2 = _interopRequireDefault(_BpmnRenderer); var _TextRenderer = require('./TextRenderer'); var _TextRenderer2 = _interopRequireDefault(_TextRenderer); var _PathMap = require('./PathMap'); var _PathMap2 = _interopRequireDefault(_PathMap); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['bpmnRenderer'], bpmnRenderer: ['type', _BpmnRenderer2.default], textRenderer: ['type', _TextRenderer2.default], pathMap: ['type', _PathMap2.default] }; },{"./BpmnRenderer":119,"./PathMap":120,"./TextRenderer":121}],123:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AutoPlace; var _ModelUtil = require('../../util/ModelUtil'); var _ModelingUtil = require('../modeling/util/ModelingUtil'); var _AutoPlaceUtil = require('./AutoPlaceUtil'); /** * A service that places elements connected to existing ones * to an appropriate position in an _automated_ fashion. * * @param {EventBus} eventBus * @param {Modeling} modeling */ function AutoPlace(eventBus, modeling) { function emit(event, payload) { return eventBus.fire(event, payload); } /** * Append shape to source at appropriate position. * * @param {djs.model.Shape} source * @param {djs.model.Shape} shape * * @return {djs.model.Shape} appended shape */ this.append = function (source, shape) { // allow others to provide the position var position = emit('autoPlace', { source: source, shape: shape }); if (!position) { position = getNewShapePosition(source, shape); } var newShape = modeling.appendShape(source, shape, position, source.parent); // notify interested parties on new shape placed emit('autoPlace.end', { shape: newShape }); return newShape; }; } AutoPlace.$inject = ['eventBus', 'modeling']; // helpers ////////////////////// /** * Find the new position for the target element to * connect to source. * * @param {djs.model.Shape} source * @param {djs.model.Shape} element * * @return {Point} */ function getNewShapePosition(source, element) { if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) { return (0, _AutoPlaceUtil.getTextAnnotationPosition)(source, element); } if ((0, _ModelingUtil.isAny)(element, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference'])) { return (0, _AutoPlaceUtil.getDataElementPosition)(source, element); } if ((0, _ModelUtil.is)(element, 'bpmn:FlowNode')) { return (0, _AutoPlaceUtil.getFlowNodePosition)(source, element); } return (0, _AutoPlaceUtil.getDefaultPosition)(source, element); } },{"../../util/ModelUtil":216,"../modeling/util/ModelingUtil":189,"./AutoPlaceUtil":125}],124:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AutoPlaceSelectionBehavior; /** * Select element after auto placement. * * @param {EventBus} eventBus * @param {Selection} selection */ function AutoPlaceSelectionBehavior(eventBus, selection) { eventBus.on('autoPlace.end', 500, function (e) { selection.select(e.shape); }); } AutoPlaceSelectionBehavior.$inject = ['eventBus', 'selection']; },{}],125:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getFlowNodePosition = getFlowNodePosition; exports.getFlowNodeDistance = getFlowNodeDistance; exports.getTextAnnotationPosition = getTextAnnotationPosition; exports.getDataElementPosition = getDataElementPosition; exports.getDefaultPosition = getDefaultPosition; exports.getConnectedAtPosition = getConnectedAtPosition; exports.deconflictPosition = deconflictPosition; var _ModelUtil = require('../../util/ModelUtil'); var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil'); var _minDash = require('min-dash'); var DEFAULT_HORIZONTAL_DISTANCE = 50; var MAX_HORIZONTAL_DISTANCE = 250; // padding to detect element placement var PLACEMENT_DETECTION_PAD = 10; /** * Always try to place element right of source; * compute actual distance from previous nodes in flow. */ function getFlowNodePosition(source, element) { var sourceTrbl = (0, _LayoutUtil.asTRBL)(source); var sourceMid = (0, _LayoutUtil.getMid)(source); var horizontalDistance = getFlowNodeDistance(source, element); var orientation = 'left', rowSize = 80, margin = 30; if ((0, _ModelUtil.is)(source, 'bpmn:BoundaryEvent')) { orientation = (0, _LayoutUtil.getOrientation)(source, source.host, -25); if (orientation.indexOf('top') !== -1) { margin *= -1; } } function getVerticalDistance(orient) { if (orient.indexOf('top') != -1) { return -1 * rowSize; } else if (orient.indexOf('bottom') != -1) { return rowSize; } else { return 0; } } var position = { x: sourceTrbl.right + horizontalDistance + element.width / 2, y: sourceMid.y + getVerticalDistance(orientation) }; var escapeDirection = { y: { margin: margin, rowSize: rowSize } }; return deconflictPosition(source, element, position, escapeDirection); } /** * Compute best distance between source and target, * based on existing connections to and from source. * * @param {djs.model.Shape} source * @param {djs.model.Shape} element * * @return {Number} distance */ function getFlowNodeDistance(source, element) { var sourceTrbl = (0, _LayoutUtil.asTRBL)(source); // is connection a reference to consider? function isReference(c) { return (0, _ModelUtil.is)(c, 'bpmn:SequenceFlow'); } function toTargetNode(weight) { return function (shape) { return { shape: shape, weight: weight, distanceTo: function distanceTo(shape) { var shapeTrbl = (0, _LayoutUtil.asTRBL)(shape); return shapeTrbl.left - sourceTrbl.right; } }; }; } function toSourceNode(weight) { return function (shape) { return { shape: shape, weight: weight, distanceTo: function distanceTo(shape) { var shapeTrbl = (0, _LayoutUtil.asTRBL)(shape); return sourceTrbl.left - shapeTrbl.right; } }; }; } // we create a list of nodes to take into consideration // for calculating the optimal flow node distance // // * weight existing target nodes higher than source nodes // * only take into account individual nodes once // var nodes = (0, _minDash.reduce)([].concat(getTargets(source, isReference).map(toTargetNode(5)), getSources(source, isReference).map(toSourceNode(1))), function (nodes, node) { // filter out shapes connected twice via source or target nodes[node.shape.id + '__weight_' + node.weight] = node; return nodes; }, {}); // compute distances between source and incoming nodes; // group at the same time by distance and expose the // favourite distance as { fav: { count, value } }. var distancesGrouped = (0, _minDash.reduce)(nodes, function (result, node) { var shape = node.shape, weight = node.weight, distanceTo = node.distanceTo; var fav = result.fav, currentDistance, currentDistanceCount, currentDistanceEntry; currentDistance = distanceTo(shape); // ignore too far away peers // or non-left to right modeled nodes if (currentDistance < 0 || currentDistance > MAX_HORIZONTAL_DISTANCE) { return result; } currentDistanceEntry = result[String(currentDistance)] = result[String(currentDistance)] || { value: currentDistance, count: 0 }; // inc diff count currentDistanceCount = currentDistanceEntry.count += 1 * weight; if (!fav || fav.count < currentDistanceCount) { result.fav = currentDistanceEntry; } return result; }, {}); if (distancesGrouped.fav) { return distancesGrouped.fav.value; } else { return DEFAULT_HORIZONTAL_DISTANCE; } } /** * Always try to place text annotations top right of source. */ function getTextAnnotationPosition(source, element) { var sourceTrbl = (0, _LayoutUtil.asTRBL)(source); var position = { x: sourceTrbl.right + element.width / 2, y: sourceTrbl.top - 50 - element.height / 2 }; var escapeDirection = { y: { margin: -30, rowSize: 20 } }; return deconflictPosition(source, element, position, escapeDirection); } /** * Always put element bottom right of source. */ function getDataElementPosition(source, element) { var sourceTrbl = (0, _LayoutUtil.asTRBL)(source); var position = { x: sourceTrbl.right - 10 + element.width / 2, y: sourceTrbl.bottom + 40 + element.width / 2 }; var escapeDirection = { x: { margin: 30, rowSize: 30 } }; return deconflictPosition(source, element, position, escapeDirection); } /** * Always put element right of source per default. */ function getDefaultPosition(source, element) { var sourceTrbl = (0, _LayoutUtil.asTRBL)(source); var sourceMid = (0, _LayoutUtil.getMid)(source); // simply put element right next to source return { x: sourceTrbl.right + DEFAULT_HORIZONTAL_DISTANCE + element.width / 2, y: sourceMid.y }; } /** * Returns all connected elements around the given source. * * This includes: * * - connected elements * - host connected elements * - attachers connected elements * * @param {djs.model.Shape} source * @param {djs.model.Shape} element * * @return {Array} */ function getAutoPlaceClosure(source, element) { var allConnected = getConnected(source); if (source.host) { allConnected = allConnected.concat(getConnected(source.host)); } if (source.attachers) { allConnected = allConnected.concat(source.attachers.reduce(function (shapes, attacher) { return shapes.concat(getConnected(attacher)); }, [])); } return allConnected; } /** * Return target at given position, if defined. * * This takes connected elements from host and attachers * into account, too. */ function getConnectedAtPosition(source, position, element) { var bounds = { x: position.x - element.width / 2, y: position.y - element.height / 2, width: element.width, height: element.height }; var closure = getAutoPlaceClosure(source, element); return (0, _minDash.find)(closure, function (target) { if (target === element) { return false; } var orientation = (0, _LayoutUtil.getOrientation)(target, bounds, PLACEMENT_DETECTION_PAD); return orientation === 'intersect'; }); } /** * Returns a new, position for the given element * based on the given element that is not occupied * by some element connected to source. * * Take into account the escapeDirection (where to move * on positining clashes) in the computation. * * @param {djs.model.Shape} source * @param {djs.model.Shape} element * @param {Point} position * @param {Object} escapeDelta * * @return {Point} */ function deconflictPosition(source, element, position, escapeDelta) { function nextPosition(existingElement) { var newPosition = { x: position.x, y: position.y }; ['x', 'y'].forEach(function (axis) { var axisDelta = escapeDelta[axis]; if (!axisDelta) { return; } var dimension = axis === 'x' ? 'width' : 'height'; var margin = axisDelta.margin, rowSize = axisDelta.rowSize; if (margin < 0) { newPosition[axis] = Math.min(existingElement[axis] + margin - element[dimension] / 2, position[axis] - rowSize + margin); } else { newPosition[axis] = Math.max(existingTarget[axis] + existingTarget[dimension] + margin + element[dimension] / 2, position[axis] + rowSize + margin); } }); return newPosition; } var existingTarget; // deconflict position until free slot is found while (existingTarget = getConnectedAtPosition(source, position, element)) { position = nextPosition(existingTarget); } return position; } // helpers ////////////////////// function noneFilter() { return true; } function getConnected(element, connectionFilter) { return [].concat(getTargets(element, connectionFilter), getSources(element, connectionFilter)); } function getSources(shape, connectionFilter) { if (!connectionFilter) { connectionFilter = noneFilter; } return shape.incoming.filter(connectionFilter).map(function (c) { return c.source; }); } function getTargets(shape, connectionFilter) { if (!connectionFilter) { connectionFilter = noneFilter; } return shape.outgoing.filter(connectionFilter).map(function (c) { return c.target; }); } },{"../../util/ModelUtil":216,"diagram-js/lib/layout/LayoutUtil":380,"min-dash":505}],126:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _AutoPlace = require('./AutoPlace'); var _AutoPlace2 = _interopRequireDefault(_AutoPlace); var _AutoPlaceSelectionBehavior = require('./AutoPlaceSelectionBehavior'); var _AutoPlaceSelectionBehavior2 = _interopRequireDefault(_AutoPlaceSelectionBehavior); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['autoPlaceSelectionBehavior'], autoPlace: ['type', _AutoPlace2.default], autoPlaceSelectionBehavior: ['type', _AutoPlaceSelectionBehavior2.default] }; },{"./AutoPlace":123,"./AutoPlaceSelectionBehavior":124}],127:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnAutoResize; var _AutoResize = require('diagram-js/lib/features/auto-resize/AutoResize'); var _AutoResize2 = _interopRequireDefault(_AutoResize); var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _ModelUtil = require('../../util/ModelUtil'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Sub class of the AutoResize module which implements a BPMN * specific resize function. */ function BpmnAutoResize(injector) { injector.invoke(_AutoResize2.default, this); } BpmnAutoResize.$inject = ['injector']; (0, _inherits2.default)(BpmnAutoResize, _AutoResize2.default); /** * Resize shapes and lanes * * @param {djs.model.Shape} target * @param {Object} newBounds */ BpmnAutoResize.prototype.resize = function (target, newBounds) { if ((0, _ModelUtil.is)(target, 'bpmn:Participant')) { this._modeling.resizeLane(target, newBounds); } else { this._modeling.resizeShape(target, newBounds); } }; },{"../../util/ModelUtil":216,"diagram-js/lib/features/auto-resize/AutoResize":260,"inherits":415}],128:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnAutoResizeProvider; var _ModelUtil = require('../../util/ModelUtil'); var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _minDash = require('min-dash'); var _AutoResizeProvider = require('diagram-js/lib/features/auto-resize/AutoResizeProvider'); var _AutoResizeProvider2 = _interopRequireDefault(_AutoResizeProvider); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * This module is a provider for automatically resizing parent BPMN elements */ function BpmnAutoResizeProvider(eventBus, modeling) { _AutoResizeProvider2.default.call(this, eventBus); this._modeling = modeling; } (0, _inherits2.default)(BpmnAutoResizeProvider, _AutoResizeProvider2.default); BpmnAutoResizeProvider.$inject = ['eventBus', 'modeling']; /** * Check if the given target can be expanded * * @param {djs.model.Shape} target * * @return {boolean} */ BpmnAutoResizeProvider.prototype.canResize = function (elements, target) { if (!(0, _ModelUtil.is)(target, 'bpmn:Participant') && !(0, _ModelUtil.is)(target, 'bpmn:Lane') && !(0, _ModelUtil.is)(target, 'bpmn:SubProcess')) { return false; } var canResize = true; (0, _minDash.forEach)(elements, function (element) { if ((0, _ModelUtil.is)(element, 'bpmn:Lane') || element.labelTarget) { canResize = false; return; } }); return canResize; }; },{"../../util/ModelUtil":216,"diagram-js/lib/features/auto-resize/AutoResizeProvider":261,"inherits":415,"min-dash":505}],129:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _BpmnAutoResize = require('./BpmnAutoResize'); var _BpmnAutoResize2 = _interopRequireDefault(_BpmnAutoResize); var _BpmnAutoResizeProvider = require('./BpmnAutoResizeProvider'); var _BpmnAutoResizeProvider2 = _interopRequireDefault(_BpmnAutoResizeProvider); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['bpmnAutoResize', 'bpmnAutoResizeProvider'], bpmnAutoResize: ['type', _BpmnAutoResize2.default], bpmnAutoResizeProvider: ['type', _BpmnAutoResizeProvider2.default] }; },{"./BpmnAutoResize":127,"./BpmnAutoResizeProvider":128}],130:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ContextPadProvider; var _minDash = require('min-dash'); var _ModelUtil = require('../../util/ModelUtil'); var _DiUtil = require('../../util/DiUtil'); var _ModelingUtil = require('../modeling/util/ModelingUtil'); var _LaneUtil = require('../modeling/util/LaneUtil'); var _Mouse = require('diagram-js/lib/util/Mouse'); /** * A provider for BPMN 2.0 elements context pad */ function ContextPadProvider(config, injector, eventBus, contextPad, modeling, elementFactory, connect, create, popupMenu, canvas, rules, translate) { config = config || {}; contextPad.registerProvider(this); this._contextPad = contextPad; this._modeling = modeling; this._elementFactory = elementFactory; this._connect = connect; this._create = create; this._popupMenu = popupMenu; this._canvas = canvas; this._rules = rules; this._translate = translate; if (config.autoPlace !== false) { this._autoPlace = injector.get('autoPlace', false); } eventBus.on('create.end', 250, function (event) { var shape = event.context.shape; if (!(0, _Mouse.hasPrimaryModifier)(event)) { return; } var entries = contextPad.getEntries(shape); if (entries.replace) { entries.replace.action.click(event, shape); } }); } ContextPadProvider.$inject = ['config.contextPad', 'injector', 'eventBus', 'contextPad', 'modeling', 'elementFactory', 'connect', 'create', 'popupMenu', 'canvas', 'rules', 'translate']; ContextPadProvider.prototype.getContextPadEntries = function (element) { var contextPad = this._contextPad, modeling = this._modeling, elementFactory = this._elementFactory, connect = this._connect, create = this._create, popupMenu = this._popupMenu, canvas = this._canvas, rules = this._rules, autoPlace = this._autoPlace, translate = this._translate; var actions = {}; if (element.type === 'label') { return actions; } var businessObject = element.businessObject; function startConnect(event, element) { connect.start(event, element); } function removeElement(e) { modeling.removeElements([element]); } function getReplaceMenuPosition(element) { var Y_OFFSET = 5; var diagramContainer = canvas.getContainer(), pad = contextPad.getPad(element).html; var diagramRect = diagramContainer.getBoundingClientRect(), padRect = pad.getBoundingClientRect(); var top = padRect.top - diagramRect.top; var left = padRect.left - diagramRect.left; var pos = { x: left, y: top + padRect.height + Y_OFFSET }; return pos; } /** * Create an append action * * @param {String} type * @param {String} className * @param {String} [title] * @param {Object} [options] * * @return {Object} descriptor */ function appendAction(type, className, title, options) { if (typeof title !== 'string') { options = title; title = translate('Append {type}', { type: type.replace(/^bpmn:/, '') }); } function appendStart(event, element) { var shape = elementFactory.createShape((0, _minDash.assign)({ type: type }, options)); create.start(event, shape, element); } var append = autoPlace ? function (event, element) { var shape = elementFactory.createShape((0, _minDash.assign)({ type: type }, options)); autoPlace.append(element, shape); } : appendStart; return { group: 'model', className: className, title: title, action: { dragstart: appendStart, click: append } }; } function splitLaneHandler(count) { return function (event, element) { // actual split modeling.splitLane(element, count); // refresh context pad after split to // get rid of split icons contextPad.open(element, true); }; } if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:Lane', 'bpmn:Participant']) && (0, _DiUtil.isExpanded)(businessObject)) { var childLanes = (0, _LaneUtil.getChildLanes)(element); (0, _minDash.assign)(actions, { 'lane-insert-above': { group: 'lane-insert-above', className: 'bpmn-icon-lane-insert-above', title: translate('Add Lane above'), action: { click: function click(event, element) { modeling.addLane(element, 'top'); } } } }); if (childLanes.length < 2) { if (element.height >= 120) { (0, _minDash.assign)(actions, { 'lane-divide-two': { group: 'lane-divide', className: 'bpmn-icon-lane-divide-two', title: translate('Divide into two Lanes'), action: { click: splitLaneHandler(2) } } }); } if (element.height >= 180) { (0, _minDash.assign)(actions, { 'lane-divide-three': { group: 'lane-divide', className: 'bpmn-icon-lane-divide-three', title: translate('Divide into three Lanes'), action: { click: splitLaneHandler(3) } } }); } } (0, _minDash.assign)(actions, { 'lane-insert-below': { group: 'lane-insert-below', className: 'bpmn-icon-lane-insert-below', title: translate('Add Lane below'), action: { click: function click(event, element) { modeling.addLane(element, 'bottom'); } } } }); } if ((0, _ModelUtil.is)(businessObject, 'bpmn:FlowNode')) { if ((0, _ModelUtil.is)(businessObject, 'bpmn:EventBasedGateway')) { (0, _minDash.assign)(actions, { 'append.receive-task': appendAction('bpmn:ReceiveTask', 'bpmn-icon-receive-task'), 'append.message-intermediate-event': appendAction('bpmn:IntermediateCatchEvent', 'bpmn-icon-intermediate-event-catch-message', translate('Append MessageIntermediateCatchEvent'), { eventDefinitionType: 'bpmn:MessageEventDefinition' }), 'append.timer-intermediate-event': appendAction('bpmn:IntermediateCatchEvent', 'bpmn-icon-intermediate-event-catch-timer', translate('Append TimerIntermediateCatchEvent'), { eventDefinitionType: 'bpmn:TimerEventDefinition' }), 'append.condtion-intermediate-event': appendAction('bpmn:IntermediateCatchEvent', 'bpmn-icon-intermediate-event-catch-condition', translate('Append ConditionIntermediateCatchEvent'), { eventDefinitionType: 'bpmn:ConditionalEventDefinition' }), 'append.signal-intermediate-event': appendAction('bpmn:IntermediateCatchEvent', 'bpmn-icon-intermediate-event-catch-signal', translate('Append SignalIntermediateCatchEvent'), { eventDefinitionType: 'bpmn:SignalEventDefinition' }) }); } else if (isEventType(businessObject, 'bpmn:BoundaryEvent', 'bpmn:CompensateEventDefinition')) { (0, _minDash.assign)(actions, { 'append.compensation-activity': appendAction('bpmn:Task', 'bpmn-icon-task', translate('Append compensation activity'), { isForCompensation: true }) }); } else if (!(0, _ModelUtil.is)(businessObject, 'bpmn:EndEvent') && !businessObject.isForCompensation && !isEventType(businessObject, 'bpmn:IntermediateThrowEvent', 'bpmn:LinkEventDefinition') && !(0, _DiUtil.isEventSubProcess)(businessObject)) { (0, _minDash.assign)(actions, { 'append.end-event': appendAction('bpmn:EndEvent', 'bpmn-icon-end-event-none'), 'append.gateway': appendAction('bpmn:ExclusiveGateway', 'bpmn-icon-gateway-none', translate('Append Gateway')), 'append.append-task': appendAction('bpmn:Task', 'bpmn-icon-task'), 'append.intermediate-event': appendAction('bpmn:IntermediateThrowEvent', 'bpmn-icon-intermediate-event-none', translate('Append Intermediate/Boundary Event')) }); } } if (!popupMenu.isEmpty(element, 'bpmn-replace')) { // Replace menu entry (0, _minDash.assign)(actions, { 'replace': { group: 'edit', className: 'bpmn-icon-screw-wrench', title: translate('Change type'), action: { click: function click(event, element) { var position = (0, _minDash.assign)(getReplaceMenuPosition(element), { cursor: { x: event.x, y: event.y } }); popupMenu.open(element, 'bpmn-replace', position); } } } }); } if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:FlowNode', 'bpmn:InteractionNode', 'bpmn:DataObjectReference', 'bpmn:DataStoreReference'])) { (0, _minDash.assign)(actions, { 'append.text-annotation': appendAction('bpmn:TextAnnotation', 'bpmn-icon-text-annotation'), 'connect': { group: 'connect', className: 'bpmn-icon-connection-multi', title: translate('Connect using ' + (businessObject.isForCompensation ? '' : 'Sequence/MessageFlow or ') + 'Association'), action: { click: startConnect, dragstart: startConnect } } }); } if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference'])) { (0, _minDash.assign)(actions, { 'connect': { group: 'connect', className: 'bpmn-icon-connection-multi', title: translate('Connect using DataInputAssociation'), action: { click: startConnect, dragstart: startConnect } } }); } // delete element entry, only show if allowed by rules var deleteAllowed = rules.allowed('elements.delete', { elements: [element] }); if ((0, _minDash.isArray)(deleteAllowed)) { // was the element returned as a deletion candidate? deleteAllowed = deleteAllowed[0] === element; } if (deleteAllowed) { (0, _minDash.assign)(actions, { 'delete': { group: 'edit', className: 'bpmn-icon-trash', title: translate('Remove'), action: { click: removeElement } } }); } return actions; }; function isEventType(eventBo, type, definition) { var isType = eventBo.$instanceOf(type); var isDefinition = false; var definitions = eventBo.eventDefinitions || []; (0, _minDash.forEach)(definitions, function (def) { if (def.$type === definition) { isDefinition = true; } }); return isType && isDefinition; } },{"../../util/DiUtil":214,"../../util/ModelUtil":216,"../modeling/util/LaneUtil":188,"../modeling/util/ModelingUtil":189,"diagram-js/lib/util/Mouse":403,"min-dash":505}],131:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _diagramJsDirectEditing = require('diagram-js-direct-editing'); var _diagramJsDirectEditing2 = _interopRequireDefault(_diagramJsDirectEditing); var _contextPad = require('diagram-js/lib/features/context-pad'); var _contextPad2 = _interopRequireDefault(_contextPad); var _selection = require('diagram-js/lib/features/selection'); var _selection2 = _interopRequireDefault(_selection); var _connect = require('diagram-js/lib/features/connect'); var _connect2 = _interopRequireDefault(_connect); var _create = require('diagram-js/lib/features/create'); var _create2 = _interopRequireDefault(_create); var _popupMenu = require('../popup-menu'); var _popupMenu2 = _interopRequireDefault(_popupMenu); var _ContextPadProvider = require('./ContextPadProvider'); var _ContextPadProvider2 = _interopRequireDefault(_ContextPadProvider); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_diagramJsDirectEditing2.default, _contextPad2.default, _selection2.default, _connect2.default, _create2.default, _popupMenu2.default], __init__: ['contextPadProvider'], contextPadProvider: ['type', _ContextPadProvider2.default] }; },{"../popup-menu":195,"./ContextPadProvider":130,"diagram-js-direct-editing":238,"diagram-js/lib/features/connect":275,"diagram-js/lib/features/context-pad":277,"diagram-js/lib/features/create":281,"diagram-js/lib/features/selection":361}],132:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnCopyPaste; var _ModelUtil = require('../../util/ModelUtil'); var _ModelCloneHelper = require('../../util/model/ModelCloneHelper'); var _ModelCloneHelper2 = _interopRequireDefault(_ModelCloneHelper); var _ModelCloneUtils = require('../../util/model/ModelCloneUtils'); var _minDash = require('min-dash'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function setProperties(descriptor, data, properties) { (0, _minDash.forEach)(properties, function (property) { if (data[property] !== undefined) { descriptor[property] = data[property]; } }); } function removeProperties(element, properties) { (0, _minDash.forEach)(properties, function (prop) { if (element[prop]) { delete element[prop]; } }); } function BpmnCopyPaste(bpmnFactory, eventBus, copyPaste, clipboard, canvas, bpmnRules) { var helper = new _ModelCloneHelper2.default(eventBus, bpmnFactory); copyPaste.registerDescriptor(function (element, descriptor) { var businessObject = descriptor.oldBusinessObject = (0, _ModelUtil.getBusinessObject)(element); var colors = {}; descriptor.type = element.type; setProperties(descriptor, businessObject.di, ['isExpanded']); setProperties(colors, businessObject.di, ['fill', 'stroke']); descriptor.colors = colors; if (element.type === 'label') { return descriptor; } setProperties(descriptor, businessObject, ['processRef', 'triggeredByEvent']); if (businessObject.default) { descriptor.default = businessObject.default.id; } return descriptor; }); eventBus.on('element.paste', function (context) { var descriptor = context.descriptor, createdElements = context.createdElements, parent = descriptor.parent, rootElement = canvas.getRootElement(), oldBusinessObject = descriptor.oldBusinessObject, newBusinessObject, source, target, canConnect; newBusinessObject = bpmnFactory.create(oldBusinessObject.$type); var properties = (0, _ModelCloneUtils.getProperties)(oldBusinessObject.$descriptor); properties = (0, _minDash.filter)(properties, function (property) { return _ModelCloneUtils.IGNORED_PROPERTIES.indexOf(property.replace(/bpmn:/, '')) === -1; }); descriptor.businessObject = helper.clone(oldBusinessObject, newBusinessObject, properties); if (descriptor.type === 'label') { return; } if ((0, _ModelUtil.is)(parent, 'bpmn:Process')) { descriptor.parent = (0, _ModelUtil.is)(rootElement, 'bpmn:Collaboration') ? rootElement : parent; } if (descriptor.type === 'bpmn:DataOutputAssociation' || descriptor.type === 'bpmn:DataInputAssociation' || descriptor.type === 'bpmn:MessageFlow') { descriptor.parent = rootElement; } if ((0, _ModelUtil.is)(parent, 'bpmn:Lane')) { descriptor.parent = parent.parent; } // make sure that the correct type of connection is created if (descriptor.waypoints) { source = createdElements[descriptor.source]; target = createdElements[descriptor.target]; if (source && target) { source = source.element; target = target.element; } canConnect = bpmnRules.canConnect(source, target); if (canConnect) { descriptor.type = canConnect.type; } } // remove the id or else we cannot paste multiple times delete newBusinessObject.id; // assign an ID bpmnFactory._ensureId(newBusinessObject); if (descriptor.type === 'bpmn:Participant' && descriptor.processRef) { descriptor.processRef = newBusinessObject.processRef = bpmnFactory.create('bpmn:Process'); } setProperties(newBusinessObject, descriptor, ['isExpanded', 'triggeredByEvent']); removeProperties(descriptor, ['triggeredByEvent']); }); } BpmnCopyPaste.$inject = ['bpmnFactory', 'eventBus', 'copyPaste', 'clipboard', 'canvas', 'bpmnRules']; },{"../../util/ModelUtil":216,"../../util/model/ModelCloneHelper":218,"../../util/model/ModelCloneUtils":219,"min-dash":505}],133:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _copyPaste = require('diagram-js/lib/features/copy-paste'); var _copyPaste2 = _interopRequireDefault(_copyPaste); var _BpmnCopyPaste = require('./BpmnCopyPaste'); var _BpmnCopyPaste2 = _interopRequireDefault(_BpmnCopyPaste); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_copyPaste2.default], __init__: ['bpmnCopyPaste'], bpmnCopyPaste: ['type', _BpmnCopyPaste2.default] }; },{"./BpmnCopyPaste":132,"diagram-js/lib/features/copy-paste":279}],134:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnDistributeElements; var _minDash = require('min-dash'); var _ModelingUtil = require('../modeling/util/ModelingUtil'); /** * Registers element exclude filters for elements that * currently do not support distribution. */ function BpmnDistributeElements(distributeElements) { distributeElements.registerFilter(function (elements) { return (0, _minDash.filter)(elements, function (element) { var cannotDistribute = (0, _ModelingUtil.isAny)(element, ['bpmn:Association', 'bpmn:BoundaryEvent', 'bpmn:DataInputAssociation', 'bpmn:DataOutputAssociation', 'bpmn:Lane', 'bpmn:MessageFlow', 'bpmn:Participant', 'bpmn:SequenceFlow', 'bpmn:TextAnnotation']); return !(element.labelTarget || cannotDistribute); }); }); } BpmnDistributeElements.$inject = ['distributeElements']; },{"../modeling/util/ModelingUtil":189,"min-dash":505}],135:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _distributeElements = require('diagram-js/lib/features/distribute-elements'); var _distributeElements2 = _interopRequireDefault(_distributeElements); var _BpmnDistributeElements = require('./BpmnDistributeElements'); var _BpmnDistributeElements2 = _interopRequireDefault(_BpmnDistributeElements); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_distributeElements2.default], __init__: ['bpmnDistributeElements'], bpmnDistributeElements: ['type', _BpmnDistributeElements2.default] }; },{"./BpmnDistributeElements":134,"diagram-js/lib/features/distribute-elements":283}],136:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnEditorActions; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _EditorActions = require('diagram-js/lib/features/editor-actions/EditorActions'); var _EditorActions2 = _interopRequireDefault(_EditorActions); var _minDash = require('min-dash'); var _ModelUtil = require('../../util/ModelUtil'); var _Elements = require('diagram-js/lib/util/Elements'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Registers and executes BPMN specific editor actions. * * @param {Injector} injector */ function BpmnEditorActions(injector) { injector.invoke(_EditorActions2.default, this); } (0, _inherits2.default)(BpmnEditorActions, _EditorActions2.default); BpmnEditorActions.$inject = ['injector']; /** * Register default actions. * * @param {Injector} injector */ BpmnEditorActions.prototype._registerDefaultActions = function (injector) { // (0) invoke super method _EditorActions2.default.prototype._registerDefaultActions.call(this, injector); // (1) retrieve optional components to integrate with var canvas = injector.get('canvas', false); var elementRegistry = injector.get('elementRegistry', false); var selection = injector.get('selection', false); var spaceTool = injector.get('spaceTool', false); var lassoTool = injector.get('lassoTool', false); var handTool = injector.get('handTool', false); var globalConnect = injector.get('globalConnect', false); var distributeElements = injector.get('distributeElements', false); var alignElements = injector.get('alignElements', false); var directEditing = injector.get('directEditing', false); var searchPad = injector.get('searchPad', false); var modeling = injector.get('modeling', false); // (2) check components and register actions if (canvas && elementRegistry && selection) { this._registerAction('selectElements', function () { // select all elements except for the invisible // root element var rootElement = canvas.getRootElement(); var elements = elementRegistry.filter(function (element) { return element !== rootElement; }); selection.select(elements); return elements; }); } if (spaceTool) { this._registerAction('spaceTool', function () { spaceTool.toggle(); }); } if (lassoTool) { this._registerAction('lassoTool', function () { lassoTool.toggle(); }); } if (handTool) { this._registerAction('handTool', function () { handTool.toggle(); }); } if (globalConnect) { this._registerAction('globalConnectTool', function () { globalConnect.toggle(); }); } if (selection && distributeElements) { this._registerAction('distributeElements', function (opts) { var currentSelection = selection.get(), type = opts.type; if (currentSelection.length) { distributeElements.trigger(currentSelection, type); } }); } if (selection && alignElements) { this._registerAction('alignElements', function (opts) { var currentSelection = selection.get(), aligneableElements = [], type = opts.type; if (currentSelection.length) { aligneableElements = (0, _minDash.filter)(currentSelection, function (element) { return !(0, _ModelUtil.is)(element, 'bpmn:Lane'); }); alignElements.trigger(aligneableElements, type); } }); } if (selection && modeling) { this._registerAction('setColor', function (opts) { var currentSelection = selection.get(); if (currentSelection.length) { modeling.setColor(currentSelection, opts); } }); } if (selection && directEditing) { this._registerAction('directEditing', function () { var currentSelection = selection.get(); if (currentSelection.length) { directEditing.activate(currentSelection[0]); } }); } if (searchPad) { this._registerAction('find', function () { searchPad.toggle(); }); } if (canvas && modeling) { this._registerAction('moveToOrigin', function () { var rootElement = canvas.getRootElement(), boundingBox, elements; if ((0, _ModelUtil.is)(rootElement, 'bpmn:Collaboration')) { elements = elementRegistry.filter(function (element) { return (0, _ModelUtil.is)(element.parent, 'bpmn:Collaboration'); }); } else { elements = elementRegistry.filter(function (element) { return element !== rootElement && !(0, _ModelUtil.is)(element.parent, 'bpmn:SubProcess'); }); } boundingBox = (0, _Elements.getBBox)(elements); modeling.moveElements(elements, { x: -boundingBox.x, y: -boundingBox.y }, rootElement); }); } }; },{"../../util/ModelUtil":216,"diagram-js/lib/features/editor-actions/EditorActions":287,"diagram-js/lib/util/Elements":396,"inherits":415,"min-dash":505}],137:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _editorActions = require('diagram-js/lib/features/editor-actions'); var _editorActions2 = _interopRequireDefault(_editorActions); var _BpmnEditorActions = require('./BpmnEditorActions'); var _BpmnEditorActions2 = _interopRequireDefault(_BpmnEditorActions); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_editorActions2.default], editorActions: ['type', _BpmnEditorActions2.default] }; },{"./BpmnEditorActions":136,"diagram-js/lib/features/editor-actions":288}],138:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnKeyboardBindings; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _KeyboardBindings = require('diagram-js/lib/features/keyboard/KeyboardBindings'); var _KeyboardBindings2 = _interopRequireDefault(_KeyboardBindings); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN 2.0 specific keyboard bindings. * * @param {Injector} injector */ function BpmnKeyboardBindings(injector) { injector.invoke(_KeyboardBindings2.default, this); } (0, _inherits2.default)(BpmnKeyboardBindings, _KeyboardBindings2.default); BpmnKeyboardBindings.$inject = ['injector']; /** * Register available keyboard bindings. * * @param {Keyboard} keyboard * @param {EditorActions} editorActions */ BpmnKeyboardBindings.prototype.registerBindings = function (keyboard, editorActions) { // inherit default bindings _KeyboardBindings2.default.prototype.registerBindings.call(this, keyboard, editorActions); /** * Add keyboard binding if respective editor action * is registered. * * @param {String} action name * @param {Function} fn that implements the key binding */ function addListener(action, fn) { if (editorActions.isRegistered(action)) { keyboard.addListener(fn); } } // select all elements // CTRL + A addListener('selectElements', function (context) { var event = context.keyEvent; if (keyboard.isKey(['a', 'A'], event) && keyboard.isCmd(event)) { editorActions.trigger('selectElements'); return true; } }); // search labels // CTRL + F addListener('find', function (context) { var event = context.keyEvent; if (keyboard.isKey(['f', 'F'], event) && keyboard.isCmd(event)) { editorActions.trigger('find'); return true; } }); // activate space tool // S addListener('spaceTool', function (context) { var event = context.keyEvent; if (keyboard.hasModifier(event)) { return; } if (keyboard.isKey(['s', 'S'], event)) { editorActions.trigger('spaceTool'); return true; } }); // activate lasso tool // L addListener('lassoTool', function (context) { var event = context.keyEvent; if (keyboard.hasModifier(event)) { return; } if (keyboard.isKey(['l', 'L'], event)) { editorActions.trigger('lassoTool'); return true; } }); // activate hand tool // H addListener('handTool', function (context) { var event = context.keyEvent; if (keyboard.hasModifier(event)) { return; } if (keyboard.isKey(['h', 'H'], event)) { editorActions.trigger('handTool'); return true; } }); // activate global connect tool // C addListener('globalConnectTool', function (context) { var event = context.keyEvent; if (keyboard.hasModifier(event)) { return; } if (keyboard.isKey(['c', 'C'], event)) { editorActions.trigger('globalConnectTool'); return true; } }); // activate direct editing // E addListener('directEditing', function (context) { var event = context.keyEvent; if (keyboard.hasModifier(event)) { return; } if (keyboard.isKey(['e', 'E'], event)) { editorActions.trigger('directEditing'); return true; } }); }; },{"diagram-js/lib/features/keyboard/KeyboardBindings":298,"inherits":415}],139:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _keyboard = require('diagram-js/lib/features/keyboard'); var _keyboard2 = _interopRequireDefault(_keyboard); var _BpmnKeyboardBindings = require('./BpmnKeyboardBindings'); var _BpmnKeyboardBindings2 = _interopRequireDefault(_BpmnKeyboardBindings); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_keyboard2.default], __init__: ['keyboardBindings'], keyboardBindings: ['type', _BpmnKeyboardBindings2.default] }; },{"./BpmnKeyboardBindings":138,"diagram-js/lib/features/keyboard":300}],140:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = LabelEditingPreview; var _tinySvg = require('tiny-svg'); var _ModelUtil = require('../../util/ModelUtil'); var _SvgTransformUtil = require('diagram-js/lib/util/SvgTransformUtil'); var MARKER_HIDDEN = 'djs-element-hidden', MARKER_LABEL_HIDDEN = 'djs-label-hidden'; function LabelEditingPreview(eventBus, canvas, elementRegistry, pathMap) { var self = this; var defaultLayer = canvas.getDefaultLayer(); var element, absoluteElementBBox, gfx; eventBus.on('directEditing.activate', function (context) { var activeProvider = context.active; element = activeProvider.element.label || activeProvider.element; // text annotation if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) { absoluteElementBBox = canvas.getAbsoluteBBox(element); gfx = (0, _tinySvg.create)('g'); var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.0, my: 0.0 } }); var path = self.path = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(path, { d: textPathData, strokeWidth: 2, stroke: getStrokeColor(element) }); (0, _tinySvg.append)(gfx, path); (0, _tinySvg.append)(defaultLayer, gfx); (0, _SvgTransformUtil.translate)(gfx, element.x, element.y); } if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation') || element.labelTarget) { canvas.addMarker(element, MARKER_HIDDEN); } else if ((0, _ModelUtil.is)(element, 'bpmn:Task') || (0, _ModelUtil.is)(element, 'bpmn:CallActivity') || (0, _ModelUtil.is)(element, 'bpmn:SubProcess') || (0, _ModelUtil.is)(element, 'bpmn:Participant')) { canvas.addMarker(element, MARKER_LABEL_HIDDEN); } }); eventBus.on('directEditing.resize', function (context) { // text annotation if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) { var height = context.height, dy = context.dy; var newElementHeight = Math.max(element.height / absoluteElementBBox.height * (height + dy), 0); var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: newElementHeight, position: { mx: 0.0, my: 0.0 } }); (0, _tinySvg.attr)(self.path, { d: textPathData }); } }); eventBus.on(['directEditing.complete', 'directEditing.cancel'], function (context) { var activeProvider = context.active; if (activeProvider) { canvas.removeMarker(activeProvider.element.label || activeProvider.element, MARKER_HIDDEN); canvas.removeMarker(element, MARKER_LABEL_HIDDEN); } element = undefined; absoluteElementBBox = undefined; if (gfx) { (0, _tinySvg.remove)(gfx); gfx = undefined; } }); } LabelEditingPreview.$inject = ['eventBus', 'canvas', 'elementRegistry', 'pathMap']; // helpers /////////////////// function getStrokeColor(element, defaultColor) { var bo = (0, _ModelUtil.getBusinessObject)(element); return bo.di.get('stroke') || defaultColor || 'black'; } },{"../../util/ModelUtil":216,"diagram-js/lib/util/SvgTransformUtil":408,"tiny-svg":535}],141:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = LabelEditingProvider; var _minDash = require('min-dash'); var _LabelUtil = require('./LabelUtil'); var _ModelUtil = require('../../util/ModelUtil'); var _ModelingUtil = require('../modeling/util/ModelingUtil'); var _DiUtil = require('../../util/DiUtil'); var _LabelUtil2 = require('../../util/LabelUtil'); function LabelEditingProvider(eventBus, canvas, directEditing, modeling, resizeHandles, textRenderer) { this._canvas = canvas; this._modeling = modeling; this._textRenderer = textRenderer; directEditing.registerProvider(this); // listen to dblclick on non-root elements eventBus.on('element.dblclick', function (event) { activateDirectEdit(event.element, true); }); // complete on followup canvas operation eventBus.on(['element.mousedown', 'drag.init', 'canvas.viewbox.changing', 'autoPlace', 'popupMenu.open'], function (event) { if (directEditing.isActive()) { directEditing.complete(); } }); // cancel on command stack changes eventBus.on(['commandStack.changed'], function (e) { if (directEditing.isActive()) { directEditing.cancel(); } }); eventBus.on('directEditing.activate', function (event) { resizeHandles.removeResizers(); }); eventBus.on('create.end', 500, function (event) { var element = event.shape, canExecute = event.context.canExecute, isTouch = event.isTouch; // TODO(nikku): we need to find a way to support the // direct editing on mobile devices; right now this will // break for desworkflowediting on mobile devices // as it breaks the user interaction workflow // TODO(nre): we should temporarily focus the edited element // here and release the focused viewport after the direct edit // operation is finished if (isTouch) { return; } if (!canExecute) { return; } activateDirectEdit(element); }); eventBus.on('autoPlace.end', 500, function (event) { activateDirectEdit(event.shape); }); function activateDirectEdit(element, force) { if (force || (0, _ModelingUtil.isAny)(element, ['bpmn:Task', 'bpmn:TextAnnotation']) || isCollapsedSubProcess(element)) { directEditing.activate(element); } } } LabelEditingProvider.$inject = ['eventBus', 'canvas', 'directEditing', 'modeling', 'resizeHandles', 'textRenderer']; /** * Activate direct editing for activities and text annotations. * * @param {djs.model.Base} element * * @return {Object} an object with properties bounds (position and size), text and options */ LabelEditingProvider.prototype.activate = function (element) { // text var text = (0, _LabelUtil.getLabel)(element); if (text === undefined) { return; } var context = { text: text }; // bounds var bounds = this.getEditingBBox(element); (0, _minDash.assign)(context, bounds); var options = {}; // tasks if ((0, _ModelingUtil.isAny)(element, ['bpmn:Task', 'bpmn:Participant', 'bpmn:Lane', 'bpmn:CallActivity']) || isCollapsedSubProcess(element)) { (0, _minDash.assign)(options, { centerVertically: true }); } // external labels if ((0, _LabelUtil2.isLabelExternal)(element)) { (0, _minDash.assign)(options, { autoResize: true }); } // text annotations if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) { (0, _minDash.assign)(options, { resizable: true, autoResize: true }); } (0, _minDash.assign)(context, { options: options }); return context; }; /** * Get the editing bounding box based on the element's size and position * * @param {djs.model.Base} element * * @return {Object} an object containing information about position * and size (fixed or minimum and/or maximum) */ LabelEditingProvider.prototype.getEditingBBox = function (element) { var canvas = this._canvas; var target = element.label || element; var bbox = canvas.getAbsoluteBBox(target); var mid = { x: bbox.x + bbox.width / 2, y: bbox.y + bbox.height / 2 }; // default position var bounds = { x: bbox.x, y: bbox.y }; var zoom = canvas.zoom(); var defaultStyle = this._textRenderer.getDefaultStyle(), externalStyle = this._textRenderer.getExternalStyle(); // take zoom into account var externalFontSize = externalStyle.fontSize * zoom, externalLineHeight = externalStyle.lineHeight, defaultFontSize = defaultStyle.fontSize * zoom, defaultLineHeight = defaultStyle.lineHeight; var style = { fontFamily: this._textRenderer.getDefaultStyle().fontFamily, fontWeight: this._textRenderer.getDefaultStyle().fontWeight }; // adjust for expanded pools AND lanes if ((0, _ModelUtil.is)(element, 'bpmn:Lane') || isExpandedPool(element)) { (0, _minDash.assign)(bounds, { width: bbox.height, height: 30 * zoom, x: bbox.x - bbox.height / 2 + 15 * zoom, y: mid.y - 30 * zoom / 2 }); (0, _minDash.assign)(style, { fontSize: defaultFontSize + 'px', lineHeight: defaultLineHeight, paddingTop: 7 * zoom + 'px', paddingBottom: 7 * zoom + 'px', paddingLeft: 5 * zoom + 'px', paddingRight: 5 * zoom + 'px', transform: 'rotate(-90deg)' }); } // internal labels for tasks and collapsed call activities, // sub processes and participants if ((0, _ModelingUtil.isAny)(element, ['bpmn:Task', 'bpmn:CallActivity']) || isCollapsedPool(element) || isCollapsedSubProcess(element)) { (0, _minDash.assign)(bounds, { width: bbox.width, height: bbox.height }); (0, _minDash.assign)(style, { fontSize: defaultFontSize + 'px', lineHeight: defaultLineHeight, paddingTop: 7 * zoom + 'px', paddingBottom: 7 * zoom + 'px', paddingLeft: 5 * zoom + 'px', paddingRight: 5 * zoom + 'px' }); } // internal labels for expanded sub processes if (isExpandedSubProcess(element)) { (0, _minDash.assign)(bounds, { width: bbox.width, x: bbox.x }); (0, _minDash.assign)(style, { fontSize: defaultFontSize + 'px', lineHeight: defaultLineHeight, paddingTop: 7 * zoom + 'px', paddingBottom: 7 * zoom + 'px', paddingLeft: 5 * zoom + 'px', paddingRight: 5 * zoom + 'px' }); } var width = 90 * zoom, paddingTop = 7 * zoom, paddingBottom = 4 * zoom; // external labels for events, data elements, gateways and connections if (target.labelTarget) { (0, _minDash.assign)(bounds, { width: width, height: bbox.height + paddingTop + paddingBottom, x: mid.x - width / 2, y: bbox.y - paddingTop }); (0, _minDash.assign)(style, { fontSize: externalFontSize + 'px', lineHeight: externalLineHeight, paddingTop: paddingTop + 'px', paddingBottom: paddingBottom + 'px' }); } // external label not yet created if ((0, _LabelUtil2.isLabelExternal)(target) && !(0, _LabelUtil2.hasExternalLabel)(target) && !(0, _LabelUtil2.isLabel)(target)) { var externalLabelMid = (0, _LabelUtil2.getExternalLabelMid)(element); var absoluteBBox = canvas.getAbsoluteBBox({ x: externalLabelMid.x, y: externalLabelMid.y, width: 0, height: 0 }); var height = externalFontSize + paddingTop + paddingBottom; (0, _minDash.assign)(bounds, { width: width, height: height, x: absoluteBBox.x - width / 2, y: absoluteBBox.y - height / 2 }); (0, _minDash.assign)(style, { fontSize: externalFontSize + 'px', lineHeight: externalLineHeight, paddingTop: paddingTop + 'px', paddingBottom: paddingBottom + 'px' }); } // text annotations if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) { (0, _minDash.assign)(bounds, { width: bbox.width, height: bbox.height, minWidth: 30 * zoom, minHeight: 10 * zoom }); (0, _minDash.assign)(style, { textAlign: 'left', paddingTop: 5 * zoom + 'px', paddingBottom: 7 * zoom + 'px', paddingLeft: 7 * zoom + 'px', paddingRight: 5 * zoom + 'px', fontSize: defaultFontSize + 'px', lineHeight: defaultLineHeight }); } return { bounds: bounds, style: style }; }; LabelEditingProvider.prototype.update = function (element, newLabel, activeContextText, bounds) { var newBounds, bbox; if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) { bbox = this._canvas.getAbsoluteBBox(element); newBounds = { x: element.x, y: element.y, width: element.width / bbox.width * bounds.width, height: element.height / bbox.height * bounds.height }; } if (isEmptyText(newLabel)) { newLabel = null; } this._modeling.updateLabel(element, newLabel, newBounds); }; // helpers ////////////////////// function isCollapsedSubProcess(element) { return (0, _ModelUtil.is)(element, 'bpmn:SubProcess') && !(0, _DiUtil.isExpanded)(element); } function isExpandedSubProcess(element) { return (0, _ModelUtil.is)(element, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(element); } function isCollapsedPool(element) { return (0, _ModelUtil.is)(element, 'bpmn:Participant') && !(0, _DiUtil.isExpanded)(element); } function isExpandedPool(element) { return (0, _ModelUtil.is)(element, 'bpmn:Participant') && (0, _DiUtil.isExpanded)(element); } function isEmptyText(label) { return !label || !label.trim(); } },{"../../util/DiUtil":214,"../../util/LabelUtil":215,"../../util/ModelUtil":216,"../modeling/util/ModelingUtil":189,"./LabelUtil":142,"min-dash":505}],142:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getLabel = getLabel; exports.setLabel = setLabel; var _ModelUtil = require('../../util/ModelUtil'); function getLabelAttr(semantic) { if ((0, _ModelUtil.is)(semantic, 'bpmn:FlowElement') || (0, _ModelUtil.is)(semantic, 'bpmn:Participant') || (0, _ModelUtil.is)(semantic, 'bpmn:Lane') || (0, _ModelUtil.is)(semantic, 'bpmn:SequenceFlow') || (0, _ModelUtil.is)(semantic, 'bpmn:MessageFlow')) { return 'name'; } if ((0, _ModelUtil.is)(semantic, 'bpmn:TextAnnotation')) { return 'text'; } } function getLabel(element) { var semantic = element.businessObject, attr = getLabelAttr(semantic); if (attr) { return semantic[attr] || ''; } } function setLabel(element, text, isExternal) { var semantic = element.businessObject, attr = getLabelAttr(semantic); if (attr) { semantic[attr] = text; } return element; } },{"../../util/ModelUtil":216}],143:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UpdateLabelHandler; var _LabelUtil = require('../LabelUtil'); var _LabelUtil2 = require('../../../util/LabelUtil'); var _ModelUtil = require('../../../util/ModelUtil'); var NULL_DIMENSIONS = { width: 0, height: 0 }; /** * A handler that updates the text of a BPMN element. */ function UpdateLabelHandler(modeling, textRenderer) { /** * Set the label and return the changed elements. * * Element parameter can be label itself or connection (i.e. sequence flow). * * @param {djs.model.Base} element * @param {String} text */ function setText(element, text) { // external label if present var label = element.label || element; var labelTarget = element.labelTarget || element; (0, _LabelUtil.setLabel)(label, text, labelTarget !== label); return [label, labelTarget]; } function preExecute(ctx) { var element = ctx.element, businessObject = element.businessObject, newLabel = ctx.newLabel; if (!(0, _LabelUtil2.isLabel)(element) && (0, _LabelUtil2.isLabelExternal)(element) && !(0, _LabelUtil2.hasExternalLabel)(element) && !isEmptyText(newLabel)) { // create label var paddingTop = 7; var labelCenter = (0, _LabelUtil2.getExternalLabelMid)(element); labelCenter = { x: labelCenter.x, y: labelCenter.y + paddingTop }; modeling.createLabel(element, labelCenter, { id: businessObject.id + '_label', businessObject: businessObject }); } } function execute(ctx) { ctx.oldLabel = (0, _LabelUtil.getLabel)(ctx.element); return setText(ctx.element, ctx.newLabel); } function revert(ctx) { return setText(ctx.element, ctx.oldLabel); } function postExecute(ctx) { var element = ctx.element, label = element.label || element, newLabel = ctx.newLabel, newBounds = ctx.newBounds, hints = ctx.hints || {}; if ((0, _LabelUtil2.isLabel)(label) && isEmptyText(newLabel)) { if (hints.removeShape !== false) { modeling.removeShape(label, { unsetLabel: false }); } return; } // ignore internal labels for elements except text annotations if (!(0, _LabelUtil2.isLabelExternal)(element) && !(0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) { return; } var bo = (0, _ModelUtil.getBusinessObject)(label); var text = bo.name || bo.text; // don't resize without text if (!text) { return; } // resize element based on label _or_ pre-defined bounds if (typeof newBounds === 'undefined') { newBounds = textRenderer.getExternalLabelBounds(label, text); } // setting newBounds to false or _null_ will // disable the postExecute resize operation if (newBounds) { modeling.resizeShape(label, newBounds, NULL_DIMENSIONS); } } // API this.preExecute = preExecute; this.execute = execute; this.revert = revert; this.postExecute = postExecute; } UpdateLabelHandler.$inject = ['modeling', 'textRenderer']; // helpers /////////////////////// function isEmptyText(label) { return !label || !label.trim(); } },{"../../../util/LabelUtil":215,"../../../util/ModelUtil":216,"../LabelUtil":142}],144:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _changeSupport = require('diagram-js/lib/features/change-support'); var _changeSupport2 = _interopRequireDefault(_changeSupport); var _resize = require('diagram-js/lib/features/resize'); var _resize2 = _interopRequireDefault(_resize); var _diagramJsDirectEditing = require('diagram-js-direct-editing'); var _diagramJsDirectEditing2 = _interopRequireDefault(_diagramJsDirectEditing); var _LabelEditingProvider = require('./LabelEditingProvider'); var _LabelEditingProvider2 = _interopRequireDefault(_LabelEditingProvider); var _LabelEditingPreview = require('./LabelEditingPreview'); var _LabelEditingPreview2 = _interopRequireDefault(_LabelEditingPreview); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_changeSupport2.default, _resize2.default, _diagramJsDirectEditing2.default], __init__: ['labelEditingProvider', 'labelEditingPreview'], labelEditingProvider: ['type', _LabelEditingProvider2.default], labelEditingPreview: ['type', _LabelEditingPreview2.default] }; },{"./LabelEditingPreview":140,"./LabelEditingProvider":141,"diagram-js-direct-editing":238,"diagram-js/lib/features/change-support":271,"diagram-js/lib/features/resize":352}],145:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnFactory; var _minDash = require('min-dash'); var _ModelingUtil = require('./util/ModelingUtil'); function BpmnFactory(moddle) { this._model = moddle; } BpmnFactory.$inject = ['moddle']; BpmnFactory.prototype._needsId = function (element) { return (0, _ModelingUtil.isAny)(element, ['bpmn:RootElement', 'bpmn:FlowElement', 'bpmn:MessageFlow', 'bpmn:DataAssociation', 'bpmn:Artifact', 'bpmn:Participant', 'bpmn:Lane', 'bpmn:LaneSet', 'bpmn:Process', 'bpmn:Collaboration', 'bpmndi:BPMNShape', 'bpmndi:BPMNEdge', 'bpmndi:BPMNDiagram', 'bpmndi:BPMNPlane', 'bpmn:Property']); }; BpmnFactory.prototype._ensureId = function (element) { // generate semantic ids for elements // bpmn:SequenceFlow -> SequenceFlow_ID var prefix = (element.$type || '').replace(/^[^:]*:/g, '') + '_'; if (!element.id && this._needsId(element)) { element.id = this._model.ids.nextPrefixed(prefix, element); } }; BpmnFactory.prototype.create = function (type, attrs) { var element = this._model.create(type, attrs || {}); this._ensureId(element); return element; }; BpmnFactory.prototype.createDiLabel = function () { return this.create('bpmndi:BPMNLabel', { bounds: this.createDiBounds() }); }; BpmnFactory.prototype.createDiShape = function (semantic, bounds, attrs) { return this.create('bpmndi:BPMNShape', (0, _minDash.assign)({ bpmnElement: semantic, bounds: this.createDiBounds(bounds) }, attrs)); }; BpmnFactory.prototype.createDiBounds = function (bounds) { return this.create('dc:Bounds', bounds); }; BpmnFactory.prototype.createDiWaypoints = function (waypoints) { var self = this; return (0, _minDash.map)(waypoints, function (pos) { return self.createDiWaypoint(pos); }); }; BpmnFactory.prototype.createDiWaypoint = function (point) { return this.create('dc:Point', (0, _minDash.pick)(point, ['x', 'y'])); }; BpmnFactory.prototype.createDiEdge = function (semantic, waypoints, attrs) { return this.create('bpmndi:BPMNEdge', (0, _minDash.assign)({ bpmnElement: semantic }, attrs)); }; BpmnFactory.prototype.createDiPlane = function (semantic) { return this.create('bpmndi:BPMNPlane', { bpmnElement: semantic }); }; },{"./util/ModelingUtil":189,"min-dash":505}],146:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnLayouter; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _minDash = require('min-dash'); var _BaseLayouter = require('diagram-js/lib/layout/BaseLayouter'); var _BaseLayouter2 = _interopRequireDefault(_BaseLayouter); var _ManhattanLayout = require('diagram-js/lib/layout/ManhattanLayout'); var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil'); var _DiUtil = require('../../util/DiUtil'); var _ModelUtil = require('../../util/ModelUtil'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function BpmnLayouter() {} (0, _inherits2.default)(BpmnLayouter, _BaseLayouter2.default); BpmnLayouter.prototype.layoutConnection = function (connection, hints) { hints = hints || {}; var source = connection.source, target = connection.target, waypoints = connection.waypoints, start = hints.connectionStart, end = hints.connectionEnd; var manhattanOptions, updatedWaypoints; if (!start) { start = getConnectionDocking(waypoints && waypoints[0], source); } if (!end) { end = getConnectionDocking(waypoints && waypoints[waypoints.length - 1], target); } // TODO(nikku): support vertical modeling // and invert preferredLayouts accordingly if ((0, _ModelUtil.is)(connection, 'bpmn:Association') || (0, _ModelUtil.is)(connection, 'bpmn:DataAssociation')) { if (waypoints && !isCompensationAssociation(connection)) { return [].concat([start], waypoints.slice(1, -1), [end]); } } // manhattan layout sequence / message flows if ((0, _ModelUtil.is)(connection, 'bpmn:MessageFlow')) { manhattanOptions = getMessageFlowManhattanOptions(source, target); } else // layout all connection between flow elements h:h, // // except for // // (1) outgoing of BoundaryEvents -> layout based on attach orientation and target orientation // (2) incoming / outgoing of Gateway -> v:h (outgoing), h:v (incoming) // (3) loops from / to the same element // if ((0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow') || isCompensationAssociation(connection)) { if (source === target) { manhattanOptions = { preferredLayouts: ['b:l'] }; } else if ((0, _ModelUtil.is)(source, 'bpmn:BoundaryEvent')) { manhattanOptions = { preferredLayouts: getBoundaryEventPreferredLayouts(source, target) }; } else if ((0, _ModelUtil.is)(source, 'bpmn:Gateway')) { manhattanOptions = { preferredLayouts: ['v:h'] }; } else if ((0, _ModelUtil.is)(target, 'bpmn:Gateway')) { manhattanOptions = { preferredLayouts: ['h:v'] }; } else { manhattanOptions = { preferredLayouts: ['h:h'] }; } } if (manhattanOptions) { manhattanOptions = (0, _minDash.assign)(manhattanOptions, hints); updatedWaypoints = (0, _ManhattanLayout.withoutRedundantPoints)((0, _ManhattanLayout.repairConnection)(source, target, start, end, waypoints, manhattanOptions)); } return updatedWaypoints || [start, end]; }; function getAttachOrientation(attachedElement) { var hostElement = attachedElement.host, padding = -10; return (0, _LayoutUtil.getOrientation)((0, _LayoutUtil.getMid)(attachedElement), hostElement, padding); } function getMessageFlowManhattanOptions(source, target) { return { preferredLayouts: ['straight', 'v:v'], preserveDocking: getMessageFlowPreserveDocking(source, target) }; } function getMessageFlowPreserveDocking(source, target) { // (1) docking element connected to participant has precedence if ((0, _ModelUtil.is)(target, 'bpmn:Participant')) { return 'source'; } if ((0, _ModelUtil.is)(source, 'bpmn:Participant')) { return 'target'; } // (2) docking element connected to expanded sub-process has precedence if (isExpandedSubProcess(target)) { return 'source'; } if (isExpandedSubProcess(source)) { return 'target'; } // (3) docking event has precedence if ((0, _ModelUtil.is)(target, 'bpmn:Event')) { return 'target'; } if ((0, _ModelUtil.is)(source, 'bpmn:Event')) { return 'source'; } return null; } function getConnectionDocking(point, shape) { return point ? point.original || point : (0, _LayoutUtil.getMid)(shape); } function isCompensationAssociation(connection) { var source = connection.source, target = connection.target; return (0, _ModelUtil.is)(target, 'bpmn:Activity') && (0, _ModelUtil.is)(source, 'bpmn:BoundaryEvent') && target.businessObject.isForCompensation; } function isExpandedSubProcess(element) { return (0, _ModelUtil.is)(element, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(element); } function isSame(a, b) { return a === b; } function isAnyOrientation(orientation, orientations) { return orientations.indexOf(orientation) !== -1; } var oppositeOrientationMapping = { 'top': 'bottom', 'top-right': 'bottom-left', 'top-left': 'bottom-right', 'right': 'left', 'bottom': 'top', 'bottom-right': 'top-left', 'bottom-left': 'top-right', 'left': 'right' }; var orientationDirectionMapping = { top: 't', right: 'r', bottom: 'b', left: 'l' }; function getHorizontalOrientation(orientation) { var matches = /right|left/.exec(orientation); return matches && matches[0]; } function getVerticalOrientation(orientation) { var matches = /top|bottom/.exec(orientation); return matches && matches[0]; } function isOppositeOrientation(a, b) { return oppositeOrientationMapping[a] === b; } function isOppositeHorizontalOrientation(a, b) { var horizontalOrientation = getHorizontalOrientation(a); var oppositeHorizontalOrientation = oppositeOrientationMapping[horizontalOrientation]; return b.indexOf(oppositeHorizontalOrientation) !== -1; } function isOppositeVerticalOrientation(a, b) { var verticalOrientation = getVerticalOrientation(a); var oppositeVerticalOrientation = oppositeOrientationMapping[verticalOrientation]; return b.indexOf(oppositeVerticalOrientation) !== -1; } function isHorizontalOrientation(orientation) { return orientation === 'right' || orientation === 'left'; } function getBoundaryEventPreferredLayouts(source, target) { var sourceMid = (0, _LayoutUtil.getMid)(source), targetMid = (0, _LayoutUtil.getMid)(target), attachOrientation = getAttachOrientation(source), sourceLayout, targetlayout; var isLoop = isSame(source.host, target); var attachedToSide = isAnyOrientation(attachOrientation, ['top', 'right', 'bottom', 'left']); var isHorizontalAttachOrientation = isHorizontalOrientation(attachOrientation); var targetOrientation = (0, _LayoutUtil.getOrientation)(targetMid, sourceMid, { x: source.width / 2 + target.width / 2, y: source.height / 2 + target.height / 2 }); // source layout // attached to either top, right, bottom or left side if (attachedToSide) { sourceLayout = orientationDirectionMapping[isHorizontalAttachOrientation ? getHorizontalOrientation(attachOrientation) : getVerticalOrientation(attachOrientation)]; } else // attached to either top-right, top-left, bottom-right or bottom-left corner { // loop, same vertical or opposite horizontal orientation if (isLoop || isSame(getVerticalOrientation(attachOrientation), getVerticalOrientation(targetOrientation)) || isOppositeOrientation(getHorizontalOrientation(attachOrientation), getHorizontalOrientation(targetOrientation))) { sourceLayout = orientationDirectionMapping[getVerticalOrientation(attachOrientation)]; } else { sourceLayout = orientationDirectionMapping[getHorizontalOrientation(attachOrientation)]; } } // target layout // attached to either top, right, bottom or left side if (attachedToSide) { // loop or opposite horizontal/vertical orientation if (isLoop || (isHorizontalAttachOrientation ? isOppositeHorizontalOrientation(attachOrientation, targetOrientation) : isOppositeVerticalOrientation(attachOrientation, targetOrientation))) { targetlayout = isHorizontalAttachOrientation ? 'h' : 'v'; } else { targetlayout = isHorizontalAttachOrientation ? 'v' : 'h'; } } else // attached to either top-right, top-left, bottom-right or bottom-left corner { // orientation is 'right', 'left' // or same vertical orientation but also 'right' or 'left' if (isHorizontalOrientation(targetOrientation) || isSame(getVerticalOrientation(attachOrientation), getVerticalOrientation(targetOrientation)) && getHorizontalOrientation(targetOrientation)) { targetlayout = 'h'; } else { targetlayout = 'v'; } } return [sourceLayout + ':' + targetlayout]; } },{"../../util/DiUtil":214,"../../util/ModelUtil":216,"diagram-js/lib/layout/BaseLayouter":378,"diagram-js/lib/layout/LayoutUtil":380,"diagram-js/lib/layout/ManhattanLayout":381,"inherits":415,"min-dash":505}],147:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnUpdater; var _minDash = require('min-dash'); var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _Collections = require('diagram-js/lib/util/Collections'); var _model = require('diagram-js/lib/model'); var _ModelUtil = require('../../util/ModelUtil'); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A handler responsible for updating the underlying BPMN 2.0 XML + DI * once changes on the diagram happen */ function BpmnUpdater(eventBus, bpmnFactory, connectionDocking, translate) { _CommandInterceptor2.default.call(this, eventBus); this._bpmnFactory = bpmnFactory; this._translate = translate; var self = this; // connection cropping ////////////////////// // crop connection ends during create/update function cropConnection(e) { var context = e.context, connection; if (!context.cropped) { connection = context.connection; connection.waypoints = connectionDocking.getCroppedWaypoints(connection); context.cropped = true; } } this.executed(['connection.layout', 'connection.create', 'connection.reconnectEnd', 'connection.reconnectStart'], cropConnection); this.reverted(['connection.layout'], function (e) { delete e.context.cropped; }); // BPMN + DI update ////////////////////// // update parent function updateParent(e) { var context = e.context; self.updateParent(context.shape || context.connection, context.oldParent); } function reverseUpdateParent(e) { var context = e.context; var element = context.shape || context.connection, // oldParent is the (old) new parent, because we are undoing oldParent = context.parent || context.newParent; self.updateParent(element, oldParent); } this.executed(['shape.move', 'shape.create', 'shape.delete', 'connection.create', 'connection.move', 'connection.delete'], ifBpmn(updateParent)); this.reverted(['shape.move', 'shape.create', 'shape.delete', 'connection.create', 'connection.move', 'connection.delete'], ifBpmn(reverseUpdateParent)); /* * ## Updating Parent * * When morphing a Process into a Collaboration or vice-versa, * make sure that both the *semantic* and *di* parent of each element * is updated. * */ function updateRoot(event) { var context = event.context, oldRoot = context.oldRoot, children = oldRoot.children; (0, _minDash.forEach)(children, function (child) { if ((0, _ModelUtil.is)(child, 'bpmn:BaseElement')) { self.updateParent(child); } }); } this.executed(['canvas.updateRoot'], updateRoot); this.reverted(['canvas.updateRoot'], updateRoot); // update bounds function updateBounds(e) { var shape = e.context.shape; if (!(0, _ModelUtil.is)(shape, 'bpmn:BaseElement')) { return; } self.updateBounds(shape); } this.executed(['shape.move', 'shape.create', 'shape.resize'], ifBpmn(function (event) { // exclude labels because they're handled separately during shape.changed if (event.context.shape.type === 'label') { return; } updateBounds(event); })); this.reverted(['shape.move', 'shape.create', 'shape.resize'], ifBpmn(function (event) { // exclude labels because they're handled separately during shape.changed if (event.context.shape.type === 'label') { return; } updateBounds(event); })); // Handle labels separately. This is necessary, because the label bounds have to be updated // every time its shape changes, not only on move, create and resize. eventBus.on('shape.changed', function (event) { if (event.element.type === 'label') { updateBounds({ context: { shape: event.element } }); } }); // attach / detach connection function updateConnection(e) { self.updateConnection(e.context); } this.executed(['connection.create', 'connection.move', 'connection.delete', 'connection.reconnectEnd', 'connection.reconnectStart'], ifBpmn(updateConnection)); this.reverted(['connection.create', 'connection.move', 'connection.delete', 'connection.reconnectEnd', 'connection.reconnectStart'], ifBpmn(updateConnection)); // update waypoints function updateConnectionWaypoints(e) { self.updateConnectionWaypoints(e.context.connection); } this.executed(['connection.layout', 'connection.move', 'connection.updateWaypoints', 'connection.reconnectEnd', 'connection.reconnectStart'], ifBpmn(updateConnectionWaypoints)); this.reverted(['connection.layout', 'connection.move', 'connection.updateWaypoints', 'connection.reconnectEnd', 'connection.reconnectStart'], ifBpmn(updateConnectionWaypoints)); // update Default & Conditional flows this.executed(['connection.reconnectEnd', 'connection.reconnectStart'], ifBpmn(function (e) { var context = e.context, connection = context.connection, businessObject = (0, _ModelUtil.getBusinessObject)(connection), oldSource = (0, _ModelUtil.getBusinessObject)(context.oldSource), oldTarget = (0, _ModelUtil.getBusinessObject)(context.oldTarget), newSource = (0, _ModelUtil.getBusinessObject)(connection.source), newTarget = (0, _ModelUtil.getBusinessObject)(connection.target); if (oldSource === newSource || oldTarget === newTarget) { return; } // on reconnectStart -> default flow if (oldSource && oldSource.default === businessObject) { context.default = oldSource.default; oldSource.default = undefined; } // on reconnectEnd -> default flow if (businessObject.sourceRef && businessObject.sourceRef.default && !((0, _ModelUtil.is)(newTarget, 'bpmn:Activity') || (0, _ModelUtil.is)(newTarget, 'bpmn:EndEvent') || (0, _ModelUtil.is)(newTarget, 'bpmn:Gateway') || (0, _ModelUtil.is)(newTarget, 'bpmn:IntermediateThrowEvent'))) { context.default = businessObject.sourceRef.default; businessObject.sourceRef.default = undefined; } // on reconnectStart -> conditional flow if (oldSource && businessObject.conditionExpression && !((0, _ModelUtil.is)(newSource, 'bpmn:Activity') || (0, _ModelUtil.is)(newSource, 'bpmn:Gateway'))) { context.conditionExpression = businessObject.conditionExpression; businessObject.conditionExpression = undefined; } // on reconnectEnd -> conditional flow if (oldTarget && businessObject.conditionExpression && !((0, _ModelUtil.is)(newTarget, 'bpmn:Activity') || (0, _ModelUtil.is)(newTarget, 'bpmn:EndEvent') || (0, _ModelUtil.is)(newTarget, 'bpmn:Gateway') || (0, _ModelUtil.is)(newTarget, 'bpmn:IntermediateThrowEvent'))) { context.conditionExpression = businessObject.conditionExpression; businessObject.conditionExpression = undefined; } })); this.reverted(['connection.reconnectEnd', 'connection.reconnectStart'], ifBpmn(function (e) { var context = e.context, connection = context.connection, businessObject = (0, _ModelUtil.getBusinessObject)(connection), newSource = (0, _ModelUtil.getBusinessObject)(connection.source); // default flow if (context.default) { if ((0, _ModelUtil.is)(newSource, 'bpmn:ExclusiveGateway') || (0, _ModelUtil.is)(newSource, 'bpmn:InclusiveGateway') || (0, _ModelUtil.is)(newSource, 'bpmn:Activity')) { newSource.default = context.default; } } // conditional flow if (context.conditionExpression && (0, _ModelUtil.is)(newSource, 'bpmn:Activity')) { businessObject.conditionExpression = context.conditionExpression; } })); // update attachments function updateAttachment(e) { self.updateAttachment(e.context); } this.executed(['element.updateAttachment'], ifBpmn(updateAttachment)); this.reverted(['element.updateAttachment'], ifBpmn(updateAttachment)); } (0, _inherits2.default)(BpmnUpdater, _CommandInterceptor2.default); BpmnUpdater.$inject = ['eventBus', 'bpmnFactory', 'connectionDocking', 'translate']; // implementation ////////////////////// BpmnUpdater.prototype.updateAttachment = function (context) { var shape = context.shape, businessObject = shape.businessObject, host = shape.host; businessObject.attachedToRef = host && host.businessObject; }; BpmnUpdater.prototype.updateParent = function (element, oldParent) { // do not update BPMN 2.0 label parent if (element instanceof _model.Label) { return; } // data stores in collaborations are handled seperately by DataStoreBehavior if ((0, _ModelUtil.is)(element, 'bpmn:DataStoreReference') && element.parent && (0, _ModelUtil.is)(element.parent, 'bpmn:Collaboration')) { return; } var parentShape = element.parent; var businessObject = element.businessObject, parentBusinessObject = parentShape && parentShape.businessObject, parentDi = parentBusinessObject && parentBusinessObject.di; if ((0, _ModelUtil.is)(element, 'bpmn:FlowNode')) { this.updateFlowNodeRefs(businessObject, parentBusinessObject, oldParent && oldParent.businessObject); } if ((0, _ModelUtil.is)(element, 'bpmn:DataOutputAssociation')) { if (element.source) { parentBusinessObject = element.source.businessObject; } else { parentBusinessObject = null; } } if ((0, _ModelUtil.is)(element, 'bpmn:DataInputAssociation')) { if (element.target) { parentBusinessObject = element.target.businessObject; } else { parentBusinessObject = null; } } this.updateSemanticParent(businessObject, parentBusinessObject); if ((0, _ModelUtil.is)(element, 'bpmn:DataObjectReference') && businessObject.dataObjectRef) { this.updateSemanticParent(businessObject.dataObjectRef, parentBusinessObject); } this.updateDiParent(businessObject.di, parentDi); }; BpmnUpdater.prototype.updateBounds = function (shape) { var di = shape.businessObject.di; var target = shape instanceof _model.Label ? this._getLabel(di) : di; var bounds = target.bounds; if (!bounds) { bounds = this._bpmnFactory.createDiBounds(); target.set('bounds', bounds); } (0, _minDash.assign)(bounds, { x: shape.x, y: shape.y, width: shape.width, height: shape.height }); }; BpmnUpdater.prototype.updateFlowNodeRefs = function (businessObject, newContainment, oldContainment) { if (oldContainment === newContainment) { return; } var oldRefs, newRefs; if ((0, _ModelUtil.is)(oldContainment, 'bpmn:Lane')) { oldRefs = oldContainment.get('flowNodeRef'); (0, _Collections.remove)(oldRefs, businessObject); } if ((0, _ModelUtil.is)(newContainment, 'bpmn:Lane')) { newRefs = newContainment.get('flowNodeRef'); (0, _Collections.add)(newRefs, businessObject); } }; // update existing sourceElement and targetElement di information BpmnUpdater.prototype.updateDiConnection = function (di, newSource, newTarget) { if (di.sourceElement && di.sourceElement.bpmnElement !== newSource) { di.sourceElement = newSource && newSource.di; } if (di.targetElement && di.targetElement.bpmnElement !== newTarget) { di.targetElement = newTarget && newTarget.di; } }; BpmnUpdater.prototype.updateDiParent = function (di, parentDi) { if (parentDi && !(0, _ModelUtil.is)(parentDi, 'bpmndi:BPMNPlane')) { parentDi = parentDi.$parent; } if (di.$parent === parentDi) { return; } var planeElements = (parentDi || di.$parent).get('planeElement'); if (parentDi) { planeElements.push(di); di.$parent = parentDi; } else { (0, _Collections.remove)(planeElements, di); di.$parent = null; } }; function getDefinitions(element) { while (element && !(0, _ModelUtil.is)(element, 'bpmn:Definitions')) { element = element.$parent; } return element; } BpmnUpdater.prototype.getLaneSet = function (container) { var laneSet, laneSets; // bpmn:Lane if ((0, _ModelUtil.is)(container, 'bpmn:Lane')) { laneSet = container.childLaneSet; if (!laneSet) { laneSet = this._bpmnFactory.create('bpmn:LaneSet'); container.childLaneSet = laneSet; laneSet.$parent = container; } return laneSet; } // bpmn:Participant if ((0, _ModelUtil.is)(container, 'bpmn:Participant')) { container = container.processRef; } // bpmn:FlowElementsContainer laneSets = container.get('laneSets'); laneSet = laneSets[0]; if (!laneSet) { laneSet = this._bpmnFactory.create('bpmn:LaneSet'); laneSet.$parent = container; laneSets.push(laneSet); } return laneSet; }; BpmnUpdater.prototype.updateSemanticParent = function (businessObject, newParent, visualParent) { var containment, translate = this._translate; if (businessObject.$parent === newParent) { return; } if ((0, _ModelUtil.is)(businessObject, 'bpmn:Lane')) { if (newParent) { newParent = this.getLaneSet(newParent); } containment = 'lanes'; } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:FlowElement')) { if (newParent) { if ((0, _ModelUtil.is)(newParent, 'bpmn:Participant')) { newParent = newParent.processRef; } else if ((0, _ModelUtil.is)(newParent, 'bpmn:Lane')) { do { // unwrap Lane -> LaneSet -> (Lane | FlowElementsContainer) newParent = newParent.$parent.$parent; } while ((0, _ModelUtil.is)(newParent, 'bpmn:Lane')); } } containment = 'flowElements'; } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:Artifact')) { while (newParent && !(0, _ModelUtil.is)(newParent, 'bpmn:Process') && !(0, _ModelUtil.is)(newParent, 'bpmn:SubProcess') && !(0, _ModelUtil.is)(newParent, 'bpmn:Collaboration')) { if ((0, _ModelUtil.is)(newParent, 'bpmn:Participant')) { newParent = newParent.processRef; break; } else { newParent = newParent.$parent; } } containment = 'artifacts'; } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:MessageFlow')) { containment = 'messageFlows'; } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:Participant')) { containment = 'participants'; // make sure the participants process is properly attached / detached // from the XML document var process = businessObject.processRef, definitions; if (process) { definitions = getDefinitions(businessObject.$parent || newParent); if (businessObject.$parent) { (0, _Collections.remove)(definitions.get('rootElements'), process); process.$parent = null; } if (newParent) { (0, _Collections.add)(definitions.get('rootElements'), process); process.$parent = definitions; } } } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataOutputAssociation')) { containment = 'dataOutputAssociations'; } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataInputAssociation')) { containment = 'dataInputAssociations'; } if (!containment) { throw new Error(translate('no parent for {element} in {parent}', { element: businessObject.id, parent: newParent.id })); } var children; if (businessObject.$parent) { // remove from old parent children = businessObject.$parent.get(containment); (0, _Collections.remove)(children, businessObject); } if (!newParent) { businessObject.$parent = null; } else { // add to new parent children = newParent.get(containment); children.push(businessObject); businessObject.$parent = newParent; } if (visualParent) { var diChildren = visualParent.get(containment); (0, _Collections.remove)(children, businessObject); if (newParent) { if (!diChildren) { diChildren = []; newParent.set(containment, diChildren); } diChildren.push(businessObject); } } }; BpmnUpdater.prototype.updateConnectionWaypoints = function (connection) { connection.businessObject.di.set('waypoint', this._bpmnFactory.createDiWaypoints(connection.waypoints)); }; BpmnUpdater.prototype.updateConnection = function (context) { var connection = context.connection, businessObject = (0, _ModelUtil.getBusinessObject)(connection), newSource = (0, _ModelUtil.getBusinessObject)(connection.source), newTarget = (0, _ModelUtil.getBusinessObject)(connection.target), visualParent; if (!(0, _ModelUtil.is)(businessObject, 'bpmn:DataAssociation')) { var inverseSet = (0, _ModelUtil.is)(businessObject, 'bpmn:SequenceFlow'); if (businessObject.sourceRef !== newSource) { if (inverseSet) { (0, _Collections.remove)(businessObject.sourceRef && businessObject.sourceRef.get('outgoing'), businessObject); if (newSource && newSource.get('outgoing')) { newSource.get('outgoing').push(businessObject); } } businessObject.sourceRef = newSource; } if (businessObject.targetRef !== newTarget) { if (inverseSet) { (0, _Collections.remove)(businessObject.targetRef && businessObject.targetRef.get('incoming'), businessObject); if (newTarget && newTarget.get('incoming')) { newTarget.get('incoming').push(businessObject); } } businessObject.targetRef = newTarget; } } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataInputAssociation')) { // handle obnoxious isMsome sourceRef businessObject.get('sourceRef')[0] = newSource; visualParent = context.parent || context.newParent || newTarget; this.updateSemanticParent(businessObject, newTarget, parent.businessObject); } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataOutputAssociation')) { visualParent = context.parent || context.newParent || newSource; this.updateSemanticParent(businessObject, newSource, visualParent); // targetRef = new target businessObject.targetRef = newTarget; } this.updateConnectionWaypoints(connection); this.updateDiConnection(businessObject.di, newSource, newTarget); }; // helpers ////////////////////// BpmnUpdater.prototype._getLabel = function (di) { if (!di.label) { di.label = this._bpmnFactory.createDiLabel(); } return di.label; }; /** * Make sure the event listener is only called * if the touched element is a BPMN element. * * @param {Function} fn * @return {Function} guarded function */ function ifBpmn(fn) { return function (event) { var context = event.context, element = context.shape || context.connection; if ((0, _ModelUtil.is)(element, 'bpmn:BaseElement')) { fn(event); } }; } },{"../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"diagram-js/lib/model":382,"diagram-js/lib/util/Collections":393,"inherits":415,"min-dash":505}],148:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ElementFactory; var _minDash = require('min-dash'); var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _ModelUtil = require('../../util/ModelUtil'); var _DiUtil = require('../../util/DiUtil'); var _ElementFactory = require('diagram-js/lib/core/ElementFactory'); var _ElementFactory2 = _interopRequireDefault(_ElementFactory); var _LabelUtil = require('../../util/LabelUtil'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A bpmn-aware factory for diagram-js shapes */ function ElementFactory(bpmnFactory, moddle, translate) { _ElementFactory2.default.call(this); this._bpmnFactory = bpmnFactory; this._moddle = moddle; this._translate = translate; } (0, _inherits2.default)(ElementFactory, _ElementFactory2.default); ElementFactory.$inject = ['bpmnFactory', 'moddle', 'translate']; ElementFactory.prototype.baseCreate = _ElementFactory2.default.prototype.create; ElementFactory.prototype.create = function (elementType, attrs) { // no special magic for labels, // we assume their businessObjects have already been created // and wired via attrs if (elementType === 'label') { return this.baseCreate(elementType, (0, _minDash.assign)({ type: 'label' }, _LabelUtil.DEFAULT_LABEL_SIZE, attrs)); } return this.createBpmnElement(elementType, attrs); }; ElementFactory.prototype.createBpmnElement = function (elementType, attrs) { var size, translate = this._translate; attrs = attrs || {}; var businessObject = attrs.businessObject; if (!businessObject) { if (!attrs.type) { throw new Error(translate('no shape type specified')); } businessObject = this._bpmnFactory.create(attrs.type); } if (!businessObject.di) { if (elementType === 'root') { businessObject.di = this._bpmnFactory.createDiPlane(businessObject, [], { id: businessObject.id + '_di' }); } else if (elementType === 'connection') { businessObject.di = this._bpmnFactory.createDiEdge(businessObject, [], { id: businessObject.id + '_di' }); } else { businessObject.di = this._bpmnFactory.createDiShape(businessObject, {}, { id: businessObject.id + '_di' }); } } if (attrs.colors) { (0, _minDash.assign)(businessObject.di, attrs.colors); delete attrs.colors; } applyAttributes(businessObject, attrs, ['processRef', 'isInterrupting', 'associationDirection', 'isForCompensation']); if (attrs.isExpanded) { applyAttribute(businessObject.di, attrs, 'isExpanded'); } if ((0, _ModelUtil.is)(businessObject, 'bpmn:ExclusiveGateway')) { businessObject.di.isMarkerVisible = true; } var eventDefinitions, newEventDefinition; if (attrs.eventDefinitionType) { eventDefinitions = businessObject.get('eventDefinitions') || []; newEventDefinition = this._moddle.create(attrs.eventDefinitionType); if (attrs.eventDefinitionType === 'bpmn:ConditionalEventDefinition') { newEventDefinition.condition = this._moddle.create('bpmn:FormalExpression'); } eventDefinitions.push(newEventDefinition); newEventDefinition.$parent = businessObject; businessObject.eventDefinitions = eventDefinitions; delete attrs.eventDefinitionType; } size = this._getDefaultSize(businessObject); attrs = (0, _minDash.assign)({ businessObject: businessObject, id: businessObject.id }, size, attrs); return this.baseCreate(elementType, attrs); }; ElementFactory.prototype._getDefaultSize = function (semantic) { if ((0, _ModelUtil.is)(semantic, 'bpmn:SubProcess')) { if ((0, _DiUtil.isExpanded)(semantic)) { return { width: 350, height: 200 }; } else { return { width: 100, height: 80 }; } } if ((0, _ModelUtil.is)(semantic, 'bpmn:Task')) { return { width: 100, height: 80 }; } if ((0, _ModelUtil.is)(semantic, 'bpmn:Gateway')) { return { width: 50, height: 50 }; } if ((0, _ModelUtil.is)(semantic, 'bpmn:Event')) { return { width: 36, height: 36 }; } if ((0, _ModelUtil.is)(semantic, 'bpmn:Participant')) { if (!(0, _DiUtil.isExpanded)(semantic)) { return { width: 400, height: 100 }; } else { return { width: 600, height: 250 }; } } if ((0, _ModelUtil.is)(semantic, 'bpmn:Lane')) { return { width: 400, height: 100 }; } if ((0, _ModelUtil.is)(semantic, 'bpmn:DataObjectReference')) { return { width: 36, height: 50 }; } if ((0, _ModelUtil.is)(semantic, 'bpmn:DataStoreReference')) { return { width: 50, height: 50 }; } if ((0, _ModelUtil.is)(semantic, 'bpmn:TextAnnotation')) { return { width: 100, height: 30 }; } return { width: 100, height: 80 }; }; ElementFactory.prototype.createParticipantShape = function (collapsed) { var attrs = { type: 'bpmn:Participant' }; if (!collapsed) { attrs.processRef = this._bpmnFactory.create('bpmn:Process'); } return this.createShape(attrs); }; // helpers ////////////////////// /** * Apply attributes from a map to the given element, * remove attribute from the map on application. * * @param {Base} element * @param {Object} attrs (in/out map of attributes) * @param {Array} attributeNames name of attributes to apply */ function applyAttributes(element, attrs, attributeNames) { (0, _minDash.forEach)(attributeNames, function (property) { if (attrs[property] !== undefined) { applyAttribute(element, attrs, property); } }); } /** * Apply named property to element and drain it from the attrs * collection. * * @param {Base} element * @param {Object} attrs (in/out map of attributes) * @param {String} attributeName to apply */ function applyAttribute(element, attrs, attributeName) { element[attributeName] = attrs[attributeName]; delete attrs[attributeName]; } },{"../../util/DiUtil":214,"../../util/LabelUtil":215,"../../util/ModelUtil":216,"diagram-js/lib/core/ElementFactory":247,"inherits":415,"min-dash":505}],149:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Modeling; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _Modeling = require('diagram-js/lib/features/modeling/Modeling'); var _Modeling2 = _interopRequireDefault(_Modeling); var _UpdatePropertiesHandler = require('./cmd/UpdatePropertiesHandler'); var _UpdatePropertiesHandler2 = _interopRequireDefault(_UpdatePropertiesHandler); var _UpdateCanvasRootHandler = require('./cmd/UpdateCanvasRootHandler'); var _UpdateCanvasRootHandler2 = _interopRequireDefault(_UpdateCanvasRootHandler); var _AddLaneHandler = require('./cmd/AddLaneHandler'); var _AddLaneHandler2 = _interopRequireDefault(_AddLaneHandler); var _SplitLaneHandler = require('./cmd/SplitLaneHandler'); var _SplitLaneHandler2 = _interopRequireDefault(_SplitLaneHandler); var _ResizeLaneHandler = require('./cmd/ResizeLaneHandler'); var _ResizeLaneHandler2 = _interopRequireDefault(_ResizeLaneHandler); var _UpdateFlowNodeRefsHandler = require('./cmd/UpdateFlowNodeRefsHandler'); var _UpdateFlowNodeRefsHandler2 = _interopRequireDefault(_UpdateFlowNodeRefsHandler); var _IdClaimHandler = require('./cmd/IdClaimHandler'); var _IdClaimHandler2 = _interopRequireDefault(_IdClaimHandler); var _SetColorHandler = require('./cmd/SetColorHandler'); var _SetColorHandler2 = _interopRequireDefault(_SetColorHandler); var _UpdateLabelHandler = require('../label-editing/cmd/UpdateLabelHandler'); var _UpdateLabelHandler2 = _interopRequireDefault(_UpdateLabelHandler); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN 2.0 modeling features activator * * @param {EventBus} eventBus * @param {ElementFactory} elementFactory * @param {CommandStack} commandStack * @param {BpmnRules} bpmnRules */ function Modeling(eventBus, elementFactory, commandStack, bpmnRules) { _Modeling2.default.call(this, eventBus, elementFactory, commandStack); this._bpmnRules = bpmnRules; } (0, _inherits2.default)(Modeling, _Modeling2.default); Modeling.$inject = ['eventBus', 'elementFactory', 'commandStack', 'bpmnRules']; Modeling.prototype.getHandlers = function () { var handlers = _Modeling2.default.prototype.getHandlers.call(this); handlers['element.updateProperties'] = _UpdatePropertiesHandler2.default; handlers['canvas.updateRoot'] = _UpdateCanvasRootHandler2.default; handlers['lane.add'] = _AddLaneHandler2.default; handlers['lane.resize'] = _ResizeLaneHandler2.default; handlers['lane.split'] = _SplitLaneHandler2.default; handlers['lane.updateRefs'] = _UpdateFlowNodeRefsHandler2.default; handlers['id.updateClaim'] = _IdClaimHandler2.default; handlers['element.setColor'] = _SetColorHandler2.default; handlers['element.updateLabel'] = _UpdateLabelHandler2.default; return handlers; }; Modeling.prototype.updateLabel = function (element, newLabel, newBounds, hints) { this._commandStack.execute('element.updateLabel', { element: element, newLabel: newLabel, newBounds: newBounds, hints: hints || {} }); }; Modeling.prototype.connect = function (source, target, attrs, hints) { var bpmnRules = this._bpmnRules; if (!attrs) { attrs = bpmnRules.canConnect(source, target); } if (!attrs) { return; } return this.createConnection(source, target, attrs, source.parent, hints); }; Modeling.prototype.updateProperties = function (element, properties) { this._commandStack.execute('element.updateProperties', { element: element, properties: properties }); }; Modeling.prototype.resizeLane = function (laneShape, newBounds, balanced) { this._commandStack.execute('lane.resize', { shape: laneShape, newBounds: newBounds, balanced: balanced }); }; Modeling.prototype.addLane = function (targetLaneShape, location) { var context = { shape: targetLaneShape, location: location }; this._commandStack.execute('lane.add', context); return context.newLane; }; Modeling.prototype.splitLane = function (targetLane, count) { this._commandStack.execute('lane.split', { shape: targetLane, count: count }); }; /** * Transform the current diagram into a collaboration. * * @return {djs.model.Root} the new root element */ Modeling.prototype.makeCollaboration = function () { var collaborationElement = this._create('root', { type: 'bpmn:Collaboration' }); var context = { newRoot: collaborationElement }; this._commandStack.execute('canvas.updateRoot', context); return collaborationElement; }; Modeling.prototype.updateLaneRefs = function (flowNodeShapes, laneShapes) { this._commandStack.execute('lane.updateRefs', { flowNodeShapes: flowNodeShapes, laneShapes: laneShapes }); }; /** * Transform the current diagram into a process. * * @return {djs.model.Root} the new root element */ Modeling.prototype.makeProcess = function () { var processElement = this._create('root', { type: 'bpmn:Process' }); var context = { newRoot: processElement }; this._commandStack.execute('canvas.updateRoot', context); }; Modeling.prototype.claimId = function (id, moddleElement) { this._commandStack.execute('id.updateClaim', { id: id, element: moddleElement, claiming: true }); }; Modeling.prototype.unclaimId = function (id, moddleElement) { this._commandStack.execute('id.updateClaim', { id: id, element: moddleElement }); }; Modeling.prototype.setColor = function (elements, colors) { if (!elements.length) { elements = [elements]; } this._commandStack.execute('element.setColor', { elements: elements, colors: colors }); }; },{"../label-editing/cmd/UpdateLabelHandler":143,"./cmd/AddLaneHandler":178,"./cmd/IdClaimHandler":179,"./cmd/ResizeLaneHandler":180,"./cmd/SetColorHandler":181,"./cmd/SplitLaneHandler":182,"./cmd/UpdateCanvasRootHandler":183,"./cmd/UpdateFlowNodeRefsHandler":184,"./cmd/UpdatePropertiesHandler":185,"diagram-js/lib/features/modeling/Modeling":305,"inherits":415}],150:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AdaptiveLabelPositioningBehavior; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil'); var _Math = require('diagram-js/lib/util/Math'); var _LabelUtil = require('../../../util/LabelUtil'); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A component that makes sure that external labels are added * together with respective elements and properly updated (DI wise) * during move. * * @param {EventBus} eventBus * @param {Modeling} modeling */ function AdaptiveLabelPositioningBehavior(eventBus, modeling) { _CommandInterceptor2.default.call(this, eventBus); this.postExecuted(['connection.create', 'connection.layout', 'connection.reconnectEnd', 'connection.reconnectStart', 'connection.updateWaypoints'], function (event) { var context = event.context, connection = context.connection; var source = connection.source, target = connection.target; checkLabelAdjustment(source); checkLabelAdjustment(target); }); this.postExecuted(['label.create'], function (event) { checkLabelAdjustment(event.context.shape.labelTarget); }); function checkLabelAdjustment(element) { // skip non-existing labels if (!(0, _LabelUtil.hasExternalLabel)(element)) { return; } var optimalPosition = getOptimalPosition(element); // no optimal position found if (!optimalPosition) { return; } adjustLabelPosition(element, optimalPosition); } var ELEMENT_LABEL_DISTANCE = 10; function adjustLabelPosition(element, orientation) { var elementMid = (0, _LayoutUtil.getMid)(element), label = element.label, labelMid = (0, _LayoutUtil.getMid)(label); var elementTrbl = (0, _LayoutUtil.asTRBL)(element); var newLabelMid; switch (orientation) { case 'top': newLabelMid = { x: elementMid.x, y: elementTrbl.top - ELEMENT_LABEL_DISTANCE - label.height / 2 }; break; case 'left': newLabelMid = { x: elementTrbl.left - ELEMENT_LABEL_DISTANCE - label.width / 2, y: elementMid.y }; break; case 'bottom': newLabelMid = { x: elementMid.x, y: elementTrbl.bottom + ELEMENT_LABEL_DISTANCE + label.height / 2 }; break; case 'right': newLabelMid = { x: elementTrbl.right + ELEMENT_LABEL_DISTANCE + label.width / 2, y: elementMid.y }; break; } var delta = (0, _Math.substract)(newLabelMid, labelMid); modeling.moveShape(label, delta); } } (0, _inherits2.default)(AdaptiveLabelPositioningBehavior, _CommandInterceptor2.default); AdaptiveLabelPositioningBehavior.$inject = ['eventBus', 'modeling']; /** * Return the optimal label position around an element * or _undefined_, if none was found. * * @param {Shape} element * * @return {String} positioning identifier */ function getOptimalPosition(element) { var labelMid = (0, _LayoutUtil.getMid)(element.label); var elementMid = (0, _LayoutUtil.getMid)(element); var labelOrientation = getApproximateOrientation(elementMid, labelMid); if (!isAligned(labelOrientation)) { return; } var takenAlignments = [].concat(element.incoming.map(function (c) { return c.waypoints[c.waypoints.length - 2]; }), element.outgoing.map(function (c) { return c.waypoints[1]; })).map(function (point) { return getApproximateOrientation(elementMid, point); }); var freeAlignments = ALIGNMENTS.filter(function (alignment) { return takenAlignments.indexOf(alignment) === -1; }); // NOTHING TO DO; label already aligned a.O.K. if (freeAlignments.indexOf(labelOrientation) !== -1) { return; } return freeAlignments[0]; } var ALIGNMENTS = ['top', 'bottom', 'left', 'right']; function getApproximateOrientation(p0, p1) { return (0, _LayoutUtil.getOrientation)(p1, p0, 5); } function isAligned(orientation) { return ALIGNMENTS.indexOf(orientation) !== -1; } },{"../../../util/LabelUtil":215,"diagram-js/lib/command/CommandInterceptor":243,"diagram-js/lib/layout/LayoutUtil":380,"diagram-js/lib/util/Math":402,"inherits":415}],151:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AppendBehavior; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _ModelUtil = require('../../../util/ModelUtil'); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function AppendBehavior(eventBus, elementFactory, bpmnRules) { _CommandInterceptor2.default.call(this, eventBus); // assign correct shape position unless already set this.preExecute('shape.append', function (context) { var source = context.source, shape = context.shape; if (!context.position) { if ((0, _ModelUtil.is)(shape, 'bpmn:TextAnnotation')) { context.position = { x: source.x + source.width / 2 + 75, y: source.y - 50 - shape.height / 2 }; } else { context.position = { x: source.x + source.width + 80 + shape.width / 2, y: source.y + source.height / 2 }; } } }, true); } (0, _inherits2.default)(AppendBehavior, _CommandInterceptor2.default); AppendBehavior.$inject = ['eventBus', 'elementFactory', 'bpmnRules']; },{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],152:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BoundaryEventBehavior; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); var _ModelUtil = require('../../../util/ModelUtil'); var _minDash = require('min-dash'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN specific boundary event behavior */ function BoundaryEventBehavior(eventBus, modeling) { _CommandInterceptor2.default.call(this, eventBus); function getBoundaryEvents(element) { return (0, _minDash.filter)(element.attachers, function (attacher) { return (0, _ModelUtil.is)(attacher, 'bpmn:BoundaryEvent'); }); } // remove after connecting to event-based gateway this.postExecute('connection.create', function (event) { var source = event.context.source, target = event.context.target, boundaryEvents = getBoundaryEvents(target); if ((0, _ModelUtil.is)(source, 'bpmn:EventBasedGateway') && (0, _ModelUtil.is)(target, 'bpmn:ReceiveTask') && boundaryEvents.length > 0) { modeling.removeElements(boundaryEvents); } }); // remove after replacing connected gateway with event-based gateway this.postExecute('connection.reconnectStart', function (event) { var oldSource = event.context.oldSource, newSource = event.context.newSource; if ((0, _ModelUtil.is)(oldSource, 'bpmn:Gateway') && (0, _ModelUtil.is)(newSource, 'bpmn:EventBasedGateway')) { (0, _minDash.forEach)(newSource.outgoing, function (connection) { var target = connection.target, attachedboundaryEvents = getBoundaryEvents(target); if ((0, _ModelUtil.is)(target, 'bpmn:ReceiveTask') && attachedboundaryEvents.length > 0) { modeling.removeElements(attachedboundaryEvents); } }); } }); } BoundaryEventBehavior.$inject = ['eventBus', 'modeling']; (0, _inherits2.default)(BoundaryEventBehavior, _CommandInterceptor2.default); },{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415,"min-dash":505}],153:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CopyPasteBehavior; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _minDash = require('min-dash'); var _ModelUtil = require('../../../util/ModelUtil'); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function CopyPasteBehavior(eventBus, modeling, canvas) { _CommandInterceptor2.default.call(this, eventBus); this.preExecute('elements.paste', 1500, function (context) { var topParent = context.topParent; // always grab the latest root if (!topParent.parent) { context.topParent = canvas.getRootElement(); } if ((0, _ModelUtil.is)(topParent, 'bpmn:Lane')) { do { // unwrap Lane -> LaneSet -> (Lane | FlowElementsContainer) topParent = context.topParent = topParent.parent; } while ((0, _ModelUtil.is)(topParent, 'bpmn:Lane') || !(0, _ModelUtil.is)(topParent, 'bpmn:Participant')); } }, true); this.postExecute('elements.paste', function (context) { var tree = context.tree, createdElements = tree.createdElements; (0, _minDash.forEach)(createdElements, function (data) { var element = data.element, businessObject = element.businessObject, descriptor = data.descriptor, defaultFlow; if (((0, _ModelUtil.is)(businessObject, 'bpmn:ExclusiveGateway') || (0, _ModelUtil.is)(businessObject, 'bpmn:InclusiveGateway') || (0, _ModelUtil.is)(businessObject, 'bpmn:Activity')) && descriptor.default) { defaultFlow = createdElements[descriptor.default]; // if the default flow wasn't created, means that it wasn't copied if (defaultFlow) { defaultFlow = defaultFlow.element; } else { defaultFlow = undefined; } delete element.default; modeling.updateProperties(element, { default: defaultFlow }); } }); }, true); } CopyPasteBehavior.$inject = ['eventBus', 'modeling', 'canvas']; (0, _inherits2.default)(CopyPasteBehavior, _CommandInterceptor2.default); },{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415,"min-dash":505}],154:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateBoundaryEventBehavior; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); var _ModelUtil = require('../../../util/ModelUtil'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN specific create boundary event behavior */ function CreateBoundaryEventBehavior(eventBus, modeling, elementFactory, bpmnFactory) { _CommandInterceptor2.default.call(this, eventBus); /** * replace intermediate event with boundary event when * attaching it to a shape */ this.preExecute('shape.create', function (context) { var shape = context.shape, host = context.host, businessObject, boundaryEvent; var attrs = { cancelActivity: true }; if (host && (0, _ModelUtil.is)(shape, 'bpmn:IntermediateThrowEvent')) { attrs.attachedToRef = host.businessObject; businessObject = bpmnFactory.create('bpmn:BoundaryEvent', attrs); boundaryEvent = { type: 'bpmn:BoundaryEvent', businessObject: businessObject }; context.shape = elementFactory.createShape(boundaryEvent); } }, true); } CreateBoundaryEventBehavior.$inject = ['eventBus', 'modeling', 'elementFactory', 'bpmnFactory']; (0, _inherits2.default)(CreateBoundaryEventBehavior, _CommandInterceptor2.default); },{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],155:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateDataObjectBehavior; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); var _ModelUtil = require('../../../util/ModelUtil'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN specific create data object behavior */ function CreateDataObjectBehavior(eventBus, bpmnFactory, moddle) { _CommandInterceptor2.default.call(this, eventBus); this.preExecute('shape.create', function (event) { var context = event.context, shape = context.shape; if ((0, _ModelUtil.is)(shape, 'bpmn:DataObjectReference') && shape.type !== 'label') { // create a DataObject every time a DataObjectReference is created var dataObject = bpmnFactory.create('bpmn:DataObject'); // set the reference to the DataObject shape.businessObject.dataObjectRef = dataObject; } }); } CreateDataObjectBehavior.$inject = ['eventBus', 'bpmnFactory', 'moddle']; (0, _inherits2.default)(CreateDataObjectBehavior, _CommandInterceptor2.default); },{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],156:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateParticipantBehavior; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); var _ModelUtil = require('../../../util/ModelUtil'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN specific create participant behavior */ function CreateParticipantBehavior(eventBus, modeling, elementFactory, bpmnFactory, canvas) { _CommandInterceptor2.default.call(this, eventBus); /** * morph process into collaboration before adding * participant onto collaboration */ this.preExecute('shape.create', function (context) { var parent = context.parent, shape = context.shape, position = context.position; var rootElement = canvas.getRootElement(); if ((0, _ModelUtil.is)(parent, 'bpmn:Process') && (0, _ModelUtil.is)(shape, 'bpmn:Participant') && !(0, _ModelUtil.is)(rootElement, 'bpmn:Collaboration')) { // this is going to detach the process root // and set the returned collaboration element // as the new root element var collaborationElement = modeling.makeCollaboration(); // monkey patch the create context // so that the participant is being dropped // onto the new collaboration root instead context.position = position; context.parent = collaborationElement; context.processRoot = parent; } }, true); this.execute('shape.create', function (context) { var processRoot = context.processRoot, shape = context.shape; if (processRoot) { context.oldProcessRef = shape.businessObject.processRef; // assign the participant processRef shape.businessObject.processRef = processRoot.businessObject; } }, true); this.revert('shape.create', function (context) { var processRoot = context.processRoot, shape = context.shape; if (processRoot) { // assign the participant processRef shape.businessObject.processRef = context.oldProcessRef; } }, true); this.postExecute('shape.create', function (context) { var processRoot = context.processRoot, shape = context.shape; if (processRoot) { // process root is already detached at this point var processChildren = processRoot.children.slice(); modeling.moveElements(processChildren, { x: 0, y: 0 }, shape); } }, true); } CreateParticipantBehavior.$inject = ['eventBus', 'modeling', 'elementFactory', 'bpmnFactory', 'canvas']; (0, _inherits2.default)(CreateParticipantBehavior, _CommandInterceptor2.default); },{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],157:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DataInputAssociationBehavior; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); var _Collections = require('diagram-js/lib/util/Collections'); var _minDash = require('min-dash'); var _ModelUtil = require('../../../util/ModelUtil'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var TARGET_REF_PLACEHOLDER_NAME = '__targetRef_placeholder'; /** * This behavior makes sure we always set a fake * DataInputAssociation#targetRef as demanded by the BPMN 2.0 * XSD schema. * * The reference is set to a bpmn:Property{ name: '__targetRef_placeholder' } * which is created on the fly and cleaned up afterwards if not needed * anymore. * * @param {EventBus} eventBus * @param {BpmnFactory} bpmnFactory */ function DataInputAssociationBehavior(eventBus, bpmnFactory) { _CommandInterceptor2.default.call(this, eventBus); this.executed(['connection.create', 'connection.delete', 'connection.move', 'connection.reconnectEnd'], ifDataInputAssociation(fixTargetRef)); this.reverted(['connection.create', 'connection.delete', 'connection.move', 'connection.reconnectEnd'], ifDataInputAssociation(fixTargetRef)); function usesTargetRef(element, targetRef, removedConnection) { var inputAssociations = element.get('dataInputAssociations'); return (0, _minDash.find)(inputAssociations, function (association) { return association !== removedConnection && association.targetRef === targetRef; }); } function getTargetRef(element, create) { var properties = element.get('properties'); var targetRefProp = (0, _minDash.find)(properties, function (p) { return p.name === TARGET_REF_PLACEHOLDER_NAME; }); if (!targetRefProp && create) { targetRefProp = bpmnFactory.create('bpmn:Property', { name: TARGET_REF_PLACEHOLDER_NAME }); (0, _Collections.add)(properties, targetRefProp); } return targetRefProp; } function cleanupTargetRef(element, connection) { var targetRefProp = getTargetRef(element); if (!targetRefProp) { return; } if (!usesTargetRef(element, targetRefProp, connection)) { (0, _Collections.remove)(element.get('properties'), targetRefProp); } } /** * Make sure targetRef is set to a valid property or * `null` if the connection is detached. * * @param {Event} event */ function fixTargetRef(event) { var context = event.context, connection = context.connection, connectionBo = connection.businessObject, target = connection.target, targetBo = target && target.businessObject, newTarget = context.newTarget, newTargetBo = newTarget && newTarget.businessObject, oldTarget = context.oldTarget || context.target, oldTargetBo = oldTarget && oldTarget.businessObject; var dataAssociation = connection.businessObject, targetRefProp; if (oldTargetBo && oldTargetBo !== targetBo) { cleanupTargetRef(oldTargetBo, connectionBo); } if (newTargetBo && newTargetBo !== targetBo) { cleanupTargetRef(newTargetBo, connectionBo); } if (targetBo) { targetRefProp = getTargetRef(targetBo, true); dataAssociation.targetRef = targetRefProp; } else { dataAssociation.targetRef = null; } } } DataInputAssociationBehavior.$inject = ['eventBus', 'bpmnFactory']; (0, _inherits2.default)(DataInputAssociationBehavior, _CommandInterceptor2.default); /** * Only call the given function when the event * touches a bpmn:DataInputAssociation. * * @param {Function} fn * @return {Function} */ function ifDataInputAssociation(fn) { return function (event) { var context = event.context, connection = context.connection; if ((0, _ModelUtil.is)(connection, 'bpmn:DataInputAssociation')) { return fn(event); } }; } },{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"diagram-js/lib/util/Collections":393,"inherits":415,"min-dash":505}],158:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DataStoreBehavior; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); var _ModelUtil = require('../../../util/ModelUtil'); var _ModelingUtil = require('../util/ModelingUtil'); var _UpdateSemanticParentHandler = require('../cmd/UpdateSemanticParentHandler'); var _UpdateSemanticParentHandler2 = _interopRequireDefault(_UpdateSemanticParentHandler); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN specific data store behavior */ function DataStoreBehavior(canvas, commandStack, elementRegistry, eventBus) { _CommandInterceptor2.default.call(this, eventBus); commandStack.registerHandler('dataStore.updateContainment', _UpdateSemanticParentHandler2.default); function getFirstParticipant() { return elementRegistry.filter(function (element) { return (0, _ModelUtil.is)(element, 'bpmn:Participant'); })[0]; } function getDataStores(element) { return element.children.filter(function (child) { return (0, _ModelUtil.is)(child, 'bpmn:DataStoreReference') && !child.labelTarget; }); } function updateDataStoreParent(dataStore, newDataStoreParent) { var dataStoreBo = dataStore.businessObject || dataStore; newDataStoreParent = newDataStoreParent || getFirstParticipant(); if (newDataStoreParent) { var newDataStoreParentBo = newDataStoreParent.businessObject || newDataStoreParent; commandStack.execute('dataStore.updateContainment', { dataStoreBo: dataStoreBo, newSemanticParent: newDataStoreParentBo.processRef || newDataStoreParentBo, newDiParent: newDataStoreParentBo.di }); } } // disable auto-resize for data stores this.preExecute('shape.create', function (event) { var context = event.context, shape = context.shape; if ((0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference') && shape.type !== 'label') { if (!context.hints) { context.hints = {}; } // prevent auto resizing context.hints.autoResize = false; } }); // disable auto-resize for data stores this.preExecute('elements.move', function (event) { var context = event.context, shapes = context.shapes; var dataStoreReferences = shapes.filter(function (shape) { return (0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference'); }); if (dataStoreReferences.length) { if (!context.hints) { context.hints = {}; } // prevent auto resizing for data store references context.hints.autoResize = shapes.filter(function (shape) { return !(0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference'); }); } }); // update parent on data store created this.postExecute('shape.create', function (event) { var context = event.context, shape = context.shape, parent = shape.parent; if ((0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference') && shape.type !== 'label' && (0, _ModelUtil.is)(parent, 'bpmn:Collaboration')) { updateDataStoreParent(shape); } }); // update parent on data store moved this.postExecute('shape.move', function (event) { var context = event.context, shape = context.shape, oldParent = context.oldParent, parent = shape.parent; if ((0, _ModelUtil.is)(oldParent, 'bpmn:Collaboration')) { // do nothing if not necessary return; } if ((0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference') && shape.type !== 'label' && (0, _ModelUtil.is)(parent, 'bpmn:Collaboration')) { var participant = (0, _ModelUtil.is)(oldParent, 'bpmn:Participant') ? oldParent : getAncestor(oldParent, 'bpmn:Participant'); updateDataStoreParent(shape, participant); } }); // update data store parents on participant or subprocess deleted this.postExecute('shape.delete', function (event) { var context = event.context, shape = context.shape, rootElement = canvas.getRootElement(); if ((0, _ModelingUtil.isAny)(shape, ['bpmn:Participant', 'bpmn:SubProcess']) && (0, _ModelUtil.is)(rootElement, 'bpmn:Collaboration')) { getDataStores(rootElement).filter(function (dataStore) { return isDescendant(dataStore, shape); }).forEach(function (dataStore) { updateDataStoreParent(dataStore); }); } }); // update data store parents on collaboration -> process this.postExecute('canvas.updateRoot', function (event) { var context = event.context, oldRoot = context.oldRoot, newRoot = context.newRoot; var dataStores = getDataStores(oldRoot); dataStores.forEach(function (dataStore) { if ((0, _ModelUtil.is)(newRoot, 'bpmn:Process')) { updateDataStoreParent(dataStore, newRoot); } }); }); } DataStoreBehavior.$inject = ['canvas', 'commandStack', 'elementRegistry', 'eventBus']; (0, _inherits2.default)(DataStoreBehavior, _CommandInterceptor2.default); // helpers ////////// function isDescendant(descendant, ancestor) { var descendantBo = descendant.businessObject || descendant, ancestorBo = ancestor.businessObject || ancestor; while (descendantBo.$parent) { if (descendantBo.$parent === ancestorBo.processRef || ancestorBo) { return true; } descendantBo = descendantBo.$parent; } return false; } function getAncestor(element, type) { while (element.parent) { if ((0, _ModelUtil.is)(element.parent, type)) { return element.parent; } element = element.parent; } } },{"../../../util/ModelUtil":216,"../cmd/UpdateSemanticParentHandler":186,"../util/ModelingUtil":189,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],159:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DeleteLaneBehavior; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); var _ModelUtil = require('../../../util/ModelUtil'); var _LaneUtil = require('../util/LaneUtil'); var _Elements = require('diagram-js/lib/util/Elements'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 500; /** * BPMN specific delete lane behavior */ function DeleteLaneBehavior(eventBus, modeling, spaceTool) { _CommandInterceptor2.default.call(this, eventBus); function compensateLaneDelete(shape, oldParent) { var siblings = (0, _LaneUtil.getChildLanes)(oldParent); var topAffected = []; var bottomAffected = []; (0, _Elements.eachElement)(siblings, function (element) { if (element.y > shape.y) { bottomAffected.push(element); } else { topAffected.push(element); } return element.children; }); if (!siblings.length) { return; } var offset; if (bottomAffected.length && topAffected.length) { offset = shape.height / 2; } else { offset = shape.height; } var topAdjustments, bottomAdjustments; if (topAffected.length) { topAdjustments = spaceTool.calculateAdjustments(topAffected, 'y', offset, shape.y - 10); spaceTool.makeSpace(topAdjustments.movingShapes, topAdjustments.resizingShapes, { x: 0, y: offset }, 's'); } if (bottomAffected.length) { bottomAdjustments = spaceTool.calculateAdjustments(bottomAffected, 'y', -offset, shape.y + shape.height + 10); spaceTool.makeSpace(bottomAdjustments.movingShapes, bottomAdjustments.resizingShapes, { x: 0, y: -offset }, 'n'); } } /** * Adjust sizes of other lanes after lane deletion */ this.postExecuted('shape.delete', LOW_PRIORITY, function (event) { var context = event.context, hints = context.hints, shape = context.shape, oldParent = context.oldParent; // only compensate lane deletes if (!(0, _ModelUtil.is)(shape, 'bpmn:Lane')) { return; } // compensate root deletes only if (hints && hints.nested) { return; } compensateLaneDelete(shape, oldParent); }); } DeleteLaneBehavior.$inject = ['eventBus', 'modeling', 'spaceTool']; (0, _inherits2.default)(DeleteLaneBehavior, _CommandInterceptor2.default); },{"../../../util/ModelUtil":216,"../util/LaneUtil":188,"diagram-js/lib/command/CommandInterceptor":243,"diagram-js/lib/util/Elements":396,"inherits":415}],160:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DropOnFlowBehavior; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _minDash = require('min-dash'); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); var _LineIntersection = require('diagram-js/lib/util/LineIntersection'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function DropOnFlowBehavior(eventBus, bpmnRules, modeling) { _CommandInterceptor2.default.call(this, eventBus); /** * Reconnect start / end of a connection after * dropping an element on a flow. */ function insertShape(shape, targetFlow, position) { var waypoints = targetFlow.waypoints, waypointsBefore, waypointsAfter, dockingPoint, source, target, incomingConnection, outgoingConnection, oldOutgoing = shape.outgoing.slice(), oldIncoming = shape.incoming.slice(); var intersection = (0, _LineIntersection.getApproxIntersection)(waypoints, position); if (intersection) { waypointsBefore = waypoints.slice(0, intersection.index); waypointsAfter = waypoints.slice(intersection.index + (intersection.bendpoint ? 1 : 0)); // due to inaccuracy intersection might have been found if (!waypointsBefore.length || !waypointsAfter.length) { return; } dockingPoint = intersection.bendpoint ? waypoints[intersection.index] : position; // if last waypointBefore is inside shape's bounds, ignore docking point if (!isPointInsideBBox(shape, waypointsBefore[waypointsBefore.length - 1])) { waypointsBefore.push(copy(dockingPoint)); } // if first waypointAfter is inside shape's bounds, ignore docking point if (!isPointInsideBBox(shape, waypointsAfter[0])) { waypointsAfter.unshift(copy(dockingPoint)); } } source = targetFlow.source; target = targetFlow.target; if (bpmnRules.canConnect(source, shape, targetFlow)) { // reconnect source -> inserted shape modeling.reconnectEnd(targetFlow, shape, waypointsBefore || position); incomingConnection = targetFlow; } if (bpmnRules.canConnect(shape, target, targetFlow)) { if (!incomingConnection) { // reconnect inserted shape -> end modeling.reconnectStart(targetFlow, shape, waypointsAfter || position); outgoingConnection = targetFlow; } else { outgoingConnection = modeling.connect(shape, target, { type: targetFlow.type, waypoints: waypointsAfter }); } } var duplicateConnections = [].concat(incomingConnection && (0, _minDash.filter)(oldIncoming, function (connection) { return connection.source === incomingConnection.source; }) || [], outgoingConnection && (0, _minDash.filter)(oldOutgoing, function (connection) { return connection.source === outgoingConnection.source; }) || []); if (duplicateConnections.length) { modeling.removeElements(duplicateConnections); } } this.preExecute('elements.move', function (context) { var newParent = context.newParent, shapes = context.shapes, delta = context.delta, shape = shapes[0]; if (!shape || !newParent) { return; } // if the new parent is a connection, // change it to the new parent's parent if (newParent && newParent.waypoints) { context.newParent = newParent = newParent.parent; } var shapeMid = getMid(shape); var newShapeMid = { x: shapeMid.x + delta.x, y: shapeMid.y + delta.y }; // find a connection which intersects with the // element's mid point var connection = (0, _minDash.find)(newParent.children, function (element) { var canInsert = bpmnRules.canInsert(shapes, element); return canInsert && (0, _LineIntersection.getApproxIntersection)(element.waypoints, newShapeMid); }); if (connection) { context.targetFlow = connection; context.position = newShapeMid; } }, true); this.postExecuted('elements.move', function (context) { var shapes = context.shapes, targetFlow = context.targetFlow, position = context.position; if (targetFlow) { insertShape(shapes[0], targetFlow, position); } }, true); this.preExecute('shape.create', function (context) { var parent = context.parent, shape = context.shape; if (bpmnRules.canInsert(shape, parent)) { context.targetFlow = parent; context.parent = parent.parent; } }, true); this.postExecuted('shape.create', function (context) { var shape = context.shape, targetFlow = context.targetFlow, position = context.position; if (targetFlow) { insertShape(shape, targetFlow, position); } }, true); } (0, _inherits2.default)(DropOnFlowBehavior, _CommandInterceptor2.default); DropOnFlowBehavior.$inject = ['eventBus', 'bpmnRules', 'modeling']; // helpers ///////////////////// function isPointInsideBBox(bbox, point) { var x = point.x, y = point.y; return x >= bbox.x && x <= bbox.x + bbox.width && y >= bbox.y && y <= bbox.y + bbox.height; } function copy(obj) { return (0, _minDash.assign)({}, obj); } function getMid(bounds) { return { x: Math.round(bounds.x + bounds.width / 2), y: Math.round(bounds.y + bounds.height / 2) }; } },{"diagram-js/lib/command/CommandInterceptor":243,"diagram-js/lib/util/LineIntersection":401,"inherits":415,"min-dash":505}],161:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ImportDockingFix; var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil'); var _LineIntersect = require('./util/LineIntersect'); var _LineIntersect2 = _interopRequireDefault(_LineIntersect); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Fix broken dockings after DI imports. * * @param {EventBus} eventBus */ function ImportDockingFix(eventBus) { function adjustDocking(startPoint, nextPoint, elementMid) { var elementTop = { x: elementMid.x, y: elementMid.y - 50 }; var elementLeft = { x: elementMid.x - 50, y: elementMid.y }; var verticalIntersect = (0, _LineIntersect2.default)(startPoint, nextPoint, elementMid, elementTop), horizontalIntersect = (0, _LineIntersect2.default)(startPoint, nextPoint, elementMid, elementLeft); // original is horizontal or vertical center cross intersection var centerIntersect; if (verticalIntersect && horizontalIntersect) { if (getDistance(verticalIntersect, elementMid) > getDistance(horizontalIntersect, elementMid)) { centerIntersect = horizontalIntersect; } else { centerIntersect = verticalIntersect; } } else { centerIntersect = verticalIntersect || horizontalIntersect; } startPoint.original = centerIntersect; } function fixDockings(connection) { var waypoints = connection.waypoints; adjustDocking(waypoints[0], waypoints[1], (0, _LayoutUtil.getMid)(connection.source)); adjustDocking(waypoints[waypoints.length - 1], waypoints[waypoints.length - 2], (0, _LayoutUtil.getMid)(connection.target)); } eventBus.on('bpmnElement.added', function (e) { var element = e.element; if (element.waypoints) { fixDockings(element); } }); } ImportDockingFix.$inject = ['eventBus']; // helpers ////////////////////// function getDistance(p1, p2) { return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2)); } },{"./util/LineIntersect":177,"diagram-js/lib/layout/LayoutUtil":380}],162:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = LabelBehavior; var _minDash = require('min-dash'); var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _ModelUtil = require('../../../util/ModelUtil'); var _LabelUtil = require('../../../util/LabelUtil'); var _LabelLayoutUtil = require('./util/LabelLayoutUtil'); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var DEFAULT_LABEL_DIMENSIONS = { width: 90, height: 20 }; var NAME_PROPERTY = 'name'; var TEXT_PROPERTY = 'text'; /** * A component that makes sure that external labels are added * together with respective elements and properly updated (DI wise) * during move. * * @param {EventBus} eventBus * @param {Modeling} modeling * @param {BpmnFactory} bpmnFactory * @param {TextRenderer} textRenderer */ function LabelBehavior(eventBus, modeling, bpmnFactory, textRenderer) { _CommandInterceptor2.default.call(this, eventBus); // update label if name property was updated this.postExecute('element.updateProperties', function (e) { var context = e.context, element = context.element, properties = context.properties; if (NAME_PROPERTY in properties) { modeling.updateLabel(element, properties[NAME_PROPERTY]); } if (TEXT_PROPERTY in properties && (0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) { var newBounds = textRenderer.getTextAnnotationBounds({ x: element.x, y: element.y, width: element.width, height: element.height }, properties[TEXT_PROPERTY] || ''); modeling.updateLabel(element, properties.text, newBounds); } }); // create label shape after shape/connection was created this.postExecute(['shape.create', 'connection.create'], function (e) { var context = e.context; var element = context.shape || context.connection, businessObject = element.businessObject; if (!(0, _LabelUtil.isLabelExternal)(element)) { return; } // only create label if name if (!businessObject.name) { return; } var labelCenter = (0, _LabelUtil.getExternalLabelMid)(element); // we don't care about x and y var labelDimensions = textRenderer.getExternalLabelBounds(DEFAULT_LABEL_DIMENSIONS, businessObject.name || ''); modeling.createLabel(element, labelCenter, { id: businessObject.id + '_label', businessObject: businessObject, width: labelDimensions.width, height: labelDimensions.height }); }); // update label after label shape was deleted this.postExecute('shape.delete', function (event) { var context = event.context, labelTarget = context.labelTarget, hints = context.hints || {}; // check if label if (labelTarget && hints.unsetLabel !== false) { modeling.updateLabel(labelTarget, null, null, { removeShape: false }); } }); // update di information on label creation this.postExecute(['label.create'], function (event) { var context = event.context, element = context.shape, businessObject, di; // we want to trigger on real labels only if (!element.labelTarget) { return; } // we want to trigger on BPMN elements only if (!(0, _ModelUtil.is)(element.labelTarget || element, 'bpmn:BaseElement')) { return; } businessObject = element.businessObject, di = businessObject.di; if (!di.label) { di.label = bpmnFactory.create('bpmndi:BPMNLabel', { bounds: bpmnFactory.create('dc:Bounds') }); } (0, _minDash.assign)(di.label.bounds, { x: element.x, y: element.y, width: element.width, height: element.height }); }); function getVisibleLabelAdjustment(event) { var command = event.command, context = event.context, connection = context.connection, label = connection.label, hints = (0, _minDash.assign)({}, context.hints), newWaypoints = context.newWaypoints || connection.waypoints, oldWaypoints = context.oldWaypoints; if (typeof hints.startChanged === 'undefined') { hints.startChanged = command === 'connection.reconnectStart'; } if (typeof hints.endChanged === 'undefined') { hints.endChanged = command === 'connection.reconnectEnd'; } return (0, _LabelLayoutUtil.getLabelAdjustment)(label, newWaypoints, oldWaypoints, hints); } this.postExecute(['connection.layout', 'connection.reconnectEnd', 'connection.reconnectStart', 'connection.updateWaypoints'], function (event) { var label = event.context.connection.label, labelAdjustment; if (!label) { return; } labelAdjustment = getVisibleLabelAdjustment(event); modeling.moveShape(label, labelAdjustment); }); // keep label position on shape replace this.postExecute(['shape.replace'], function (event) { var context = event.context, newShape = context.newShape, oldShape = context.oldShape; var businessObject = (0, _ModelUtil.getBusinessObject)(newShape); if (businessObject && (0, _LabelUtil.isLabelExternal)(businessObject) && oldShape.label && newShape.label) { newShape.label.x = oldShape.label.x; newShape.label.y = oldShape.label.y; } }); } (0, _inherits2.default)(LabelBehavior, _CommandInterceptor2.default); LabelBehavior.$inject = ['eventBus', 'modeling', 'bpmnFactory', 'textRenderer']; },{"../../../util/LabelUtil":215,"../../../util/ModelUtil":216,"./util/LabelLayoutUtil":175,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415,"min-dash":505}],163:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ModelingFeedback; var _ModelUtil = require('../../../util/ModelUtil'); var COLLAB_ERR_MSG = 'flow elements must be children of pools/participants', PROCESS_ERR_MSG = 'participants cannot be pasted onto a non-empty process diagram'; function ModelingFeedback(eventBus, tooltips, translate) { function showError(position, message, timeout) { tooltips.add({ position: { x: position.x + 5, y: position.y + 5 }, type: 'error', timeout: timeout || 2000, html: '
' + message + '
' }); } eventBus.on(['shape.move.rejected', 'create.rejected'], function (event) { var context = event.context, shape = context.shape, target = context.target; if ((0, _ModelUtil.is)(target, 'bpmn:Collaboration') && (0, _ModelUtil.is)(shape, 'bpmn:FlowNode')) { showError(event, translate(COLLAB_ERR_MSG)); } }); eventBus.on(['elements.paste.rejected'], function (event) { var context = event.context, position = context.position, target = context.target; if ((0, _ModelUtil.is)(target, 'bpmn:Collaboration')) { showError(position, translate(COLLAB_ERR_MSG)); } if ((0, _ModelUtil.is)(target, 'bpmn:Process')) { showError(position, translate(PROCESS_ERR_MSG), 3000); } }); } ModelingFeedback.$inject = ['eventBus', 'tooltips', 'translate']; },{"../../../util/ModelUtil":216}],164:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = RemoveElementBehavior; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _ModelUtil = require('../../../util/ModelUtil'); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); var _LineIntersect = require('./util/LineIntersect'); var _LineIntersect2 = _interopRequireDefault(_LineIntersect); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function RemoveElementBehavior(eventBus, bpmnRules, modeling) { _CommandInterceptor2.default.call(this, eventBus); /** * Combine sequence flows when deleting an element * if there is one incoming and one outgoing * sequence flow */ this.preExecute('shape.delete', function (e) { var shape = e.context.shape; // only handle [a] -> [shape] -> [b] patterns if (shape.incoming.length !== 1 || shape.outgoing.length !== 1) { return; } var inConnection = shape.incoming[0], outConnection = shape.outgoing[0]; // only handle sequence flows if (!(0, _ModelUtil.is)(inConnection, 'bpmn:SequenceFlow') || !(0, _ModelUtil.is)(outConnection, 'bpmn:SequenceFlow')) { return; } if (bpmnRules.canConnect(inConnection.source, outConnection.target, inConnection)) { // compute new, combined waypoints var newWaypoints = getNewWaypoints(inConnection.waypoints, outConnection.waypoints); modeling.reconnectEnd(inConnection, outConnection.target, newWaypoints); } }); } (0, _inherits2.default)(RemoveElementBehavior, _CommandInterceptor2.default); RemoveElementBehavior.$inject = ['eventBus', 'bpmnRules', 'modeling']; // helpers ////////////////////// function getDocking(point) { return point.original || point; } function getNewWaypoints(inWaypoints, outWaypoints) { var intersection = (0, _LineIntersect2.default)(getDocking(inWaypoints[inWaypoints.length - 2]), getDocking(inWaypoints[inWaypoints.length - 1]), getDocking(outWaypoints[1]), getDocking(outWaypoints[0])); if (intersection) { return [].concat(inWaypoints.slice(0, inWaypoints.length - 1), [intersection], outWaypoints.slice(1)); } else { return [getDocking(inWaypoints[0]), getDocking(outWaypoints[outWaypoints.length - 1])]; } } },{"../../../util/ModelUtil":216,"./util/LineIntersect":177,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],165:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = RemoveParticipantBehavior; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); var _ModelUtil = require('../../../util/ModelUtil'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN specific remove behavior */ function RemoveParticipantBehavior(eventBus, modeling) { _CommandInterceptor2.default.call(this, eventBus); /** * morph collaboration diagram into process diagram * after the last participant has been removed */ this.preExecute('shape.delete', function (context) { var shape = context.shape, parent = shape.parent; // activate the behavior if the shape to be removed // is a participant if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) { context.collaborationRoot = parent; } }, true); this.postExecute('shape.delete', function (context) { var collaborationRoot = context.collaborationRoot; if (collaborationRoot && !collaborationRoot.businessObject.participants.length) { // replace empty collaboration with process diagram modeling.makeProcess(); } }, true); } RemoveParticipantBehavior.$inject = ['eventBus', 'modeling']; (0, _inherits2.default)(RemoveParticipantBehavior, _CommandInterceptor2.default); },{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],166:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ReplaceConnectionBehavior; var _minDash = require('min-dash'); var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); var _ModelUtil = require('../../../util/ModelUtil'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function ReplaceConnectionBehavior(eventBus, modeling, bpmnRules) { _CommandInterceptor2.default.call(this, eventBus); function fixConnection(connection) { var source = connection.source, target = connection.target, parent = connection.parent; // do not do anything if connection // is already deleted (may happen due to other // behaviors plugged-in before) if (!parent) { return; } var replacementType, remove; /** * Check if incoming or outgoing connections * can stay or could be substituted with an * appropriate replacement. * * This holds true for SequenceFlow <> MessageFlow. */ if ((0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow')) { if (!bpmnRules.canConnectSequenceFlow(source, target)) { remove = true; } if (bpmnRules.canConnectMessageFlow(source, target)) { replacementType = 'bpmn:MessageFlow'; } } // transform message flows into sequence flows, if possible if ((0, _ModelUtil.is)(connection, 'bpmn:MessageFlow')) { if (!bpmnRules.canConnectMessageFlow(source, target)) { remove = true; } if (bpmnRules.canConnectSequenceFlow(source, target)) { replacementType = 'bpmn:SequenceFlow'; } } if ((0, _ModelUtil.is)(connection, 'bpmn:Association') && !bpmnRules.canConnectAssociation(source, target)) { remove = true; } // remove invalid connection, // unless it has been removed already if (remove) { modeling.removeConnection(connection); } // replace SequenceFlow <> MessageFlow if (replacementType) { modeling.connect(source, target, { type: replacementType, waypoints: connection.waypoints.slice() }); } } this.postExecuted('elements.move', function (context) { var closure = context.closure, allConnections = closure.allConnections; (0, _minDash.forEach)(allConnections, fixConnection); }, true); this.postExecuted(['connection.reconnectStart', 'connection.reconnectEnd'], function (event) { var connection = event.context.connection; fixConnection(connection); }); this.postExecuted('element.updateProperties', function (event) { var context = event.context, properties = context.properties, element = context.element, businessObject = element.businessObject, connection; // remove condition expression when morphing to default flow if (properties.default) { connection = (0, _minDash.find)(element.outgoing, (0, _minDash.matchPattern)({ id: element.businessObject.default.id })); if (connection) { modeling.updateProperties(connection, { conditionExpression: undefined }); } } // remove default property from source when morphing to conditional flow if (properties.conditionExpression && businessObject.sourceRef.default === businessObject) { modeling.updateProperties(element.source, { default: undefined }); } }); } (0, _inherits2.default)(ReplaceConnectionBehavior, _CommandInterceptor2.default); ReplaceConnectionBehavior.$inject = ['eventBus', 'modeling', 'bpmnRules']; },{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415,"min-dash":505}],167:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ReplaceElementBehaviour; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); var _minDash = require('min-dash'); var _DiUtil = require('../../../util/DiUtil'); var _ModelUtil = require('../../../util/ModelUtil'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Defines the behaviour of what happens to the elements inside a container * that morphs into another BPMN element */ function ReplaceElementBehaviour(eventBus, bpmnReplace, bpmnRules, elementRegistry, selection, modeling) { _CommandInterceptor2.default.call(this, eventBus); this._bpmnReplace = bpmnReplace; this._elementRegistry = elementRegistry; this._selection = selection; this._modeling = modeling; this.postExecuted(['elements.move'], 500, function (event) { var context = event.context, target = context.newParent, newHost = context.newHost, elements = []; (0, _minDash.forEach)(context.closure.topLevel, function (topLevelElements) { if ((0, _DiUtil.isEventSubProcess)(topLevelElements)) { elements = elements.concat(topLevelElements.children); } else { elements = elements.concat(topLevelElements); } }); // Change target to host when the moving element is a `bpmn:BoundaryEvent` if (elements.length === 1 && newHost) { target = newHost; } var canReplace = bpmnRules.canReplace(elements, target); if (canReplace) { this.replaceElements(elements, canReplace.replacements, newHost); } }, this); // update attachments if the host is replaced this.postExecute(['shape.replace'], 1500, function (e) { var context = e.context, oldShape = context.oldShape, newShape = context.newShape, attachers = oldShape.attachers, canReplace; if (attachers && attachers.length) { canReplace = bpmnRules.canReplace(attachers, newShape); this.replaceElements(attachers, canReplace.replacements); } }, this); this.postExecuted(['shape.replace'], 1500, function (e) { var context = e.context, oldShape = context.oldShape, newShape = context.newShape; modeling.unclaimId(oldShape.businessObject.id, oldShape.businessObject); modeling.updateProperties(newShape, { id: oldShape.id }); }); } (0, _inherits2.default)(ReplaceElementBehaviour, _CommandInterceptor2.default); ReplaceElementBehaviour.prototype.replaceElements = function (elements, newElements, newHost) { var elementRegistry = this._elementRegistry, bpmnReplace = this._bpmnReplace, selection = this._selection, modeling = this._modeling; (0, _minDash.forEach)(newElements, function (replacement) { var newElement = { type: replacement.newElementType }; var oldElement = elementRegistry.get(replacement.oldElementId); if (newHost && (0, _ModelUtil.is)(oldElement, 'bpmn:BoundaryEvent')) { modeling.updateAttachment(oldElement, null); } var idx = elements.indexOf(oldElement); elements[idx] = bpmnReplace.replaceElement(oldElement, newElement, { select: false }); if (newHost && (0, _ModelUtil.is)(elements[idx], 'bpmn:BoundaryEvent')) { modeling.updateAttachment(elements[idx], newHost); } }); if (newElements) { selection.select(elements); } }; ReplaceElementBehaviour.$inject = ['eventBus', 'bpmnReplace', 'bpmnRules', 'elementRegistry', 'selection', 'modeling']; },{"../../../util/DiUtil":214,"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415,"min-dash":505}],168:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ResizeLaneBehavior; var _ModelUtil = require('../../../util/ModelUtil'); var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil'); var _Mouse = require('diagram-js/lib/util/Mouse'); var SLIGHTLY_HIGHER_PRIORITY = 1001; /** * Invoke {@link Modeling#resizeLane} instead of * {@link Modeling#resizeShape} when resizing a Lane * or Participant shape. */ function ResizeLaneBehavior(eventBus, modeling) { eventBus.on('resize.start', SLIGHTLY_HIGHER_PRIORITY + 500, function (event) { var context = event.context, shape = context.shape; if ((0, _ModelUtil.is)(shape, 'bpmn:Lane') || (0, _ModelUtil.is)(shape, 'bpmn:Participant')) { // should we resize the opposite lane(s) in // order to compensate for the resize operation? context.balanced = !(0, _Mouse.hasPrimaryModifier)(event); } }); /** * Intercept resize end and call resize lane function instead. */ eventBus.on('resize.end', SLIGHTLY_HIGHER_PRIORITY, function (event) { var context = event.context, shape = context.shape, canExecute = context.canExecute, newBounds = context.newBounds; if ((0, _ModelUtil.is)(shape, 'bpmn:Lane') || (0, _ModelUtil.is)(shape, 'bpmn:Participant')) { if (canExecute) { // ensure we have actual pixel values for new bounds // (important when zoom level was > 1 during move) newBounds = (0, _LayoutUtil.roundBounds)(newBounds); // perform the actual resize modeling.resizeLane(shape, newBounds, context.balanced); } // stop propagation return false; } }); } ResizeLaneBehavior.$inject = ['eventBus', 'modeling']; },{"../../../util/ModelUtil":216,"diagram-js/lib/layout/LayoutUtil":380,"diagram-js/lib/util/Mouse":403}],169:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ToggleElementCollapseBehaviour; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); var _ModelUtil = require('../../../util/ModelUtil'); var _ResizeUtil = require('diagram-js/lib/features/resize/ResizeUtil'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 500; function ToggleElementCollapseBehaviour(eventBus, elementFactory, modeling, resize) { _CommandInterceptor2.default.call(this, eventBus); function hideEmptyLables(children) { if (children.length) { children.forEach(function (child) { if (child.type === 'label' && !child.businessObject.name) { child.hidden = true; } }); } } function expandedBounds(shape, defaultSize) { var children = shape.children, newBounds = defaultSize, visibleElements, visibleBBox; visibleElements = filterVisible(children).concat([shape]); visibleBBox = (0, _ResizeUtil.computeChildrenBBox)(visibleElements); if (visibleBBox) { // center to visibleBBox with max(defaultSize, childrenBounds) newBounds.width = Math.max(visibleBBox.width, newBounds.width); newBounds.height = Math.max(visibleBBox.height, newBounds.height); newBounds.x = visibleBBox.x + (visibleBBox.width - newBounds.width) / 2; newBounds.y = visibleBBox.y + (visibleBBox.height - newBounds.height) / 2; } else { // center to collapsed shape with defaultSize newBounds.x = shape.x + (shape.width - newBounds.width) / 2; newBounds.y = shape.y + (shape.height - newBounds.height) / 2; } return newBounds; } function collapsedBounds(shape, defaultSize) { return { x: shape.x + (shape.width - defaultSize.width) / 2, y: shape.y + (shape.height - defaultSize.height) / 2, width: defaultSize.width, height: defaultSize.height }; } this.executed(['shape.toggleCollapse'], LOW_PRIORITY, function (e) { var context = e.context, shape = context.shape; if (!(0, _ModelUtil.is)(shape, 'bpmn:SubProcess')) { return; } if (!shape.collapsed) { // all children got made visible through djs, hide empty labels hideEmptyLables(shape.children); // remove collapsed marker (0, _ModelUtil.getBusinessObject)(shape).di.isExpanded = true; } else { // place collapsed marker (0, _ModelUtil.getBusinessObject)(shape).di.isExpanded = false; } }); this.reverted(['shape.toggleCollapse'], LOW_PRIORITY, function (e) { var context = e.context; var shape = context.shape; // revert removing/placing collapsed marker if (!shape.collapsed) { (0, _ModelUtil.getBusinessObject)(shape).di.isExpanded = true; } else { (0, _ModelUtil.getBusinessObject)(shape).di.isExpanded = false; } }); this.postExecuted(['shape.toggleCollapse'], LOW_PRIORITY, function (e) { var shape = e.context.shape, defaultSize = elementFactory._getDefaultSize(shape), newBounds; if (shape.collapsed) { // resize to default size of collapsed shapes newBounds = collapsedBounds(shape, defaultSize); } else { // resize to bounds of max(visible children, defaultSize) newBounds = expandedBounds(shape, defaultSize); } modeling.resizeShape(shape, newBounds); }); } (0, _inherits2.default)(ToggleElementCollapseBehaviour, _CommandInterceptor2.default); ToggleElementCollapseBehaviour.$inject = ['eventBus', 'elementFactory', 'modeling']; // helpers ////////////////////// function filterVisible(elements) { return elements.filter(function (e) { return !e.hidden; }); } },{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"diagram-js/lib/features/resize/ResizeUtil":351,"inherits":415}],170:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UnclaimIdBehavior; var _minDash = require('min-dash'); var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Unclaims model IDs on element deletion. * * @param {EventBus} eventBus * @param {Modeling} modeling */ function UnclaimIdBehavior(eventBus, modeling) { _CommandInterceptor2.default.call(this, eventBus); this.preExecute('elements.delete', function (event) { var context = event.context, elements = context.elements; (0, _minDash.forEach)(elements, function (element) { modeling.unclaimId(element.businessObject.id, element.businessObject); }); }); } (0, _inherits2.default)(UnclaimIdBehavior, _CommandInterceptor2.default); UnclaimIdBehavior.$inject = ['eventBus', 'modeling']; },{"diagram-js/lib/command/CommandInterceptor":243,"inherits":415,"min-dash":505}],171:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DeleteSequenceFlowBehavior; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); var _ModelUtil = require('../../../util/ModelUtil'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A behavior that unsets the Default property of * sequence flow source on element delete, if the * removed element is the Gateway or Task's default flow. * * @param {EventBus} eventBus * @param {Modeling} modeling */ function DeleteSequenceFlowBehavior(eventBus, modeling) { _CommandInterceptor2.default.call(this, eventBus); this.preExecute('connection.delete', function (event) { var context = event.context, connection = context.connection, source = connection.source; if (isDefaultFlow(connection, source)) { modeling.updateProperties(source, { 'default': null }); } }); } (0, _inherits2.default)(DeleteSequenceFlowBehavior, _CommandInterceptor2.default); DeleteSequenceFlowBehavior.$inject = ['eventBus', 'modeling']; // helpers ////////////////////// function isDefaultFlow(connection, source) { if (!(0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow')) { return false; } var sourceBo = (0, _ModelUtil.getBusinessObject)(source), sequenceFlow = (0, _ModelUtil.getBusinessObject)(connection); return sourceBo.get('default') === sequenceFlow; } },{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],172:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UpdateFlowNodeRefsBehavior; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); var _ModelUtil = require('../../../util/ModelUtil'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 500, HIGH_PRIORITY = 5000; /** * BPMN specific delete lane behavior */ function UpdateFlowNodeRefsBehavior(eventBus, modeling, translate) { _CommandInterceptor2.default.call(this, eventBus); /** * Ok, this is it: * * We have to update the Lane#flowNodeRefs _and_ * FlowNode#lanes with every FlowNode move/resize and * Lane move/resize. * * We want to group that stuff to recompute containments * as efficient as possible. * * Yea! */ // the update context var context; function initContext() { context = context || new UpdateContext(); context.enter(); return context; } function getContext() { if (!context) { throw new Error(translate('out of bounds release')); } return context; } function releaseContext() { if (!context) { throw new Error(translate('out of bounds release')); } var triggerUpdate = context.leave(); if (triggerUpdate) { modeling.updateLaneRefs(context.flowNodes, context.lanes); context = null; } return triggerUpdate; } var laneRefUpdateEvents = ['spaceTool', 'lane.add', 'lane.resize', 'lane.split', 'elements.move', 'elements.delete', 'shape.create', 'shape.delete', 'shape.move', 'shape.resize']; // listen to a lot of stuff to group lane updates this.preExecute(laneRefUpdateEvents, HIGH_PRIORITY, function (event) { initContext(); }); this.postExecuted(laneRefUpdateEvents, LOW_PRIORITY, function (event) { releaseContext(); }); // Mark flow nodes + lanes that need an update this.preExecute(['shape.create', 'shape.move', 'shape.delete', 'shape.resize'], function (event) { var context = event.context, shape = context.shape; var updateContext = getContext(); // no need to update labels if (shape.labelTarget) { return; } if ((0, _ModelUtil.is)(shape, 'bpmn:Lane')) { updateContext.addLane(shape); } if ((0, _ModelUtil.is)(shape, 'bpmn:FlowNode')) { updateContext.addFlowNode(shape); } }); } UpdateFlowNodeRefsBehavior.$inject = ['eventBus', 'modeling', 'translate']; (0, _inherits2.default)(UpdateFlowNodeRefsBehavior, _CommandInterceptor2.default); function UpdateContext() { this.flowNodes = []; this.lanes = []; this.counter = 0; this.addLane = function (lane) { this.lanes.push(lane); }; this.addFlowNode = function (flowNode) { this.flowNodes.push(flowNode); }; this.enter = function () { this.counter++; }; this.leave = function () { this.counter--; return !this.counter; }; } },{"../../../util/ModelUtil":216,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415}],173:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _AdaptiveLabelPositioningBehavior = require('./AdaptiveLabelPositioningBehavior'); var _AdaptiveLabelPositioningBehavior2 = _interopRequireDefault(_AdaptiveLabelPositioningBehavior); var _AppendBehavior = require('./AppendBehavior'); var _AppendBehavior2 = _interopRequireDefault(_AppendBehavior); var _BoundaryEventBehavior = require('./BoundaryEventBehavior'); var _BoundaryEventBehavior2 = _interopRequireDefault(_BoundaryEventBehavior); var _CopyPasteBehavior = require('./CopyPasteBehavior'); var _CopyPasteBehavior2 = _interopRequireDefault(_CopyPasteBehavior); var _CreateBoundaryEventBehavior = require('./CreateBoundaryEventBehavior'); var _CreateBoundaryEventBehavior2 = _interopRequireDefault(_CreateBoundaryEventBehavior); var _CreateDataObjectBehavior = require('./CreateDataObjectBehavior'); var _CreateDataObjectBehavior2 = _interopRequireDefault(_CreateDataObjectBehavior); var _CreateParticipantBehavior = require('./CreateParticipantBehavior'); var _CreateParticipantBehavior2 = _interopRequireDefault(_CreateParticipantBehavior); var _DataInputAssociationBehavior = require('./DataInputAssociationBehavior'); var _DataInputAssociationBehavior2 = _interopRequireDefault(_DataInputAssociationBehavior); var _DataStoreBehavior = require('./DataStoreBehavior'); var _DataStoreBehavior2 = _interopRequireDefault(_DataStoreBehavior); var _DeleteLaneBehavior = require('./DeleteLaneBehavior'); var _DeleteLaneBehavior2 = _interopRequireDefault(_DeleteLaneBehavior); var _DropOnFlowBehavior = require('./DropOnFlowBehavior'); var _DropOnFlowBehavior2 = _interopRequireDefault(_DropOnFlowBehavior); var _ImportDockingFix = require('./ImportDockingFix'); var _ImportDockingFix2 = _interopRequireDefault(_ImportDockingFix); var _LabelBehavior = require('./LabelBehavior'); var _LabelBehavior2 = _interopRequireDefault(_LabelBehavior); var _ModelingFeedback = require('./ModelingFeedback'); var _ModelingFeedback2 = _interopRequireDefault(_ModelingFeedback); var _ReplaceConnectionBehavior = require('./ReplaceConnectionBehavior'); var _ReplaceConnectionBehavior2 = _interopRequireDefault(_ReplaceConnectionBehavior); var _RemoveParticipantBehavior = require('./RemoveParticipantBehavior'); var _RemoveParticipantBehavior2 = _interopRequireDefault(_RemoveParticipantBehavior); var _ReplaceElementBehaviour = require('./ReplaceElementBehaviour'); var _ReplaceElementBehaviour2 = _interopRequireDefault(_ReplaceElementBehaviour); var _ResizeLaneBehavior = require('./ResizeLaneBehavior'); var _ResizeLaneBehavior2 = _interopRequireDefault(_ResizeLaneBehavior); var _RemoveElementBehavior = require('./RemoveElementBehavior'); var _RemoveElementBehavior2 = _interopRequireDefault(_RemoveElementBehavior); var _ToggleElementCollapseBehaviour = require('./ToggleElementCollapseBehaviour'); var _ToggleElementCollapseBehaviour2 = _interopRequireDefault(_ToggleElementCollapseBehaviour); var _UnclaimIdBehavior = require('./UnclaimIdBehavior'); var _UnclaimIdBehavior2 = _interopRequireDefault(_UnclaimIdBehavior); var _UpdateFlowNodeRefsBehavior = require('./UpdateFlowNodeRefsBehavior'); var _UpdateFlowNodeRefsBehavior2 = _interopRequireDefault(_UpdateFlowNodeRefsBehavior); var _UnsetDefaultFlowBehavior = require('./UnsetDefaultFlowBehavior'); var _UnsetDefaultFlowBehavior2 = _interopRequireDefault(_UnsetDefaultFlowBehavior); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['adaptiveLabelPositioningBehavior', 'appendBehavior', 'boundaryEventBehavior', 'copyPasteBehavior', 'createBoundaryEventBehavior', 'createDataObjectBehavior', 'dataStoreBehavior', 'createParticipantBehavior', 'dataInputAssociationBehavior', 'deleteLaneBehavior', 'dropOnFlowBehavior', 'importDockingFix', 'labelBehavior', 'modelingFeedback', 'removeElementBehavior', 'removeParticipantBehavior', 'replaceConnectionBehavior', 'replaceElementBehaviour', 'resizeLaneBehavior', 'toggleElementCollapseBehaviour', 'unclaimIdBehavior', 'unsetDefaultFlowBehavior', 'updateFlowNodeRefsBehavior'], adaptiveLabelPositioningBehavior: ['type', _AdaptiveLabelPositioningBehavior2.default], appendBehavior: ['type', _AppendBehavior2.default], boundaryEventBehavior: ['type', _BoundaryEventBehavior2.default], copyPasteBehavior: ['type', _CopyPasteBehavior2.default], createBoundaryEventBehavior: ['type', _CreateBoundaryEventBehavior2.default], createDataObjectBehavior: ['type', _CreateDataObjectBehavior2.default], createParticipantBehavior: ['type', _CreateParticipantBehavior2.default], dataInputAssociationBehavior: ['type', _DataInputAssociationBehavior2.default], dataStoreBehavior: ['type', _DataStoreBehavior2.default], deleteLaneBehavior: ['type', _DeleteLaneBehavior2.default], dropOnFlowBehavior: ['type', _DropOnFlowBehavior2.default], importDockingFix: ['type', _ImportDockingFix2.default], labelBehavior: ['type', _LabelBehavior2.default], modelingFeedback: ['type', _ModelingFeedback2.default], replaceConnectionBehavior: ['type', _ReplaceConnectionBehavior2.default], removeParticipantBehavior: ['type', _RemoveParticipantBehavior2.default], replaceElementBehaviour: ['type', _ReplaceElementBehaviour2.default], resizeLaneBehavior: ['type', _ResizeLaneBehavior2.default], removeElementBehavior: ['type', _RemoveElementBehavior2.default], toggleElementCollapseBehaviour: ['type', _ToggleElementCollapseBehaviour2.default], unclaimIdBehavior: ['type', _UnclaimIdBehavior2.default], updateFlowNodeRefsBehavior: ['type', _UpdateFlowNodeRefsBehavior2.default], unsetDefaultFlowBehavior: ['type', _UnsetDefaultFlowBehavior2.default] }; },{"./AdaptiveLabelPositioningBehavior":150,"./AppendBehavior":151,"./BoundaryEventBehavior":152,"./CopyPasteBehavior":153,"./CreateBoundaryEventBehavior":154,"./CreateDataObjectBehavior":155,"./CreateParticipantBehavior":156,"./DataInputAssociationBehavior":157,"./DataStoreBehavior":158,"./DeleteLaneBehavior":159,"./DropOnFlowBehavior":160,"./ImportDockingFix":161,"./LabelBehavior":162,"./ModelingFeedback":163,"./RemoveElementBehavior":164,"./RemoveParticipantBehavior":165,"./ReplaceConnectionBehavior":166,"./ReplaceElementBehaviour":167,"./ResizeLaneBehavior":168,"./ToggleElementCollapseBehaviour":169,"./UnclaimIdBehavior":170,"./UnsetDefaultFlowBehavior":171,"./UpdateFlowNodeRefsBehavior":172}],174:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.vectorLength = vectorLength; exports.getAngle = getAngle; exports.rotateVector = rotateVector; exports.perpendicularFoot = perpendicularFoot; exports.getDistancePointLine = getDistancePointLine; exports.getDistancePointPoint = getDistancePointPoint; /** * Returns the length of a vector * * @param {Vector} * @return {Float} */ function vectorLength(v) { return Math.sqrt(Math.pow(v.x, 2) + Math.pow(v.y, 2)); } /** * Calculates the angle between a line a the yAxis * * @param {Array} * @return {Float} */ function getAngle(line) { // return value is between 0, 180 and -180, -0 // @janstuemmel: maybe replace return a/b with b/a return Math.atan((line[1].y - line[0].y) / (line[1].x - line[0].x)); } /** * Rotates a vector by a given angle * * @param {Vector} * @param {Float} Angle in radians * @return {Vector} */ function rotateVector(vector, angle) { return !angle ? vector : { x: Math.cos(angle) * vector.x - Math.sin(angle) * vector.y, y: Math.sin(angle) * vector.x + Math.cos(angle) * vector.y }; } /** * Solves a 2D equation system * a + r*b = c, where a,b,c are 2D vectors * * @param {Vector} * @param {Vector} * @param {Vector} * @return {Float} */ function solveLambaSystem(a, b, c) { // the 2d system var system = [{ n: a[0] - c[0], lambda: b[0] }, { n: a[1] - c[1], lambda: b[1] }]; // solve var n = system[0].n * b[0] + system[1].n * b[1], l = system[0].lambda * b[0] + system[1].lambda * b[1]; return -n / l; } /** * Position of perpendicular foot * * @param {Point} * @param [ {Point}, {Point} ] line defined throug two points * @return {Point} the perpendicular foot position */ function perpendicularFoot(point, line) { var a = line[0], b = line[1]; // relative position of b from a var bd = { x: b.x - a.x, y: b.y - a.y }; // solve equation system to the parametrized vectors param real value var r = solveLambaSystem([a.x, a.y], [bd.x, bd.y], [point.x, point.y]); return { x: a.x + r * bd.x, y: a.y + r * bd.y }; } /** * Calculates the distance between a point and a line * * @param {Point} * @param [ {Point}, {Point} ] line defined throug two points * @return {Float} distance */ function getDistancePointLine(point, line) { var pfPoint = perpendicularFoot(point, line); // distance vector var connectionVector = { x: pfPoint.x - point.x, y: pfPoint.y - point.y }; return vectorLength(connectionVector); } /** * Calculates the distance between two points * * @param {Point} * @param {Point} * @return {Float} distance */ function getDistancePointPoint(point1, point2) { return vectorLength({ x: point1.x - point2.x, y: point1.y - point2.y }); } },{}],175:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.findNewLabelLineStartIndex = findNewLabelLineStartIndex; exports.getLabelAdjustment = getLabelAdjustment; var _GeometricUtil = require('./GeometricUtil'); var _LineAttachmentUtil = require('./LineAttachmentUtil'); var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil'); function findNewLabelLineStartIndex(oldWaypoints, newWaypoints, attachment, hints) { var index = attachment.segmentIndex; var offset = newWaypoints.length - oldWaypoints.length; // segmentMove happend if (hints.segmentMove) { var oldSegmentStartIndex = hints.segmentMove.segmentStartIndex, newSegmentStartIndex = hints.segmentMove.newSegmentStartIndex; // if label was on moved segment return new segment index if (index === oldSegmentStartIndex) { return newSegmentStartIndex; } // label is after new segment index if (index >= newSegmentStartIndex) { return index + offset < newSegmentStartIndex ? newSegmentStartIndex : index + offset; } // if label is before new segment index return index; } // bendpointMove happend if (hints.bendpointMove) { var insert = hints.bendpointMove.insert, bendpointIndex = hints.bendpointMove.bendpointIndex, newIndex; // waypoints length didnt change if (offset === 0) { return index; } // label behind new/removed bendpoint if (index >= bendpointIndex) { newIndex = insert ? index + 1 : index - 1; } // label before new/removed bendpoint if (index < bendpointIndex) { newIndex = index; // decide label should take right or left segment if (insert && attachment.type !== 'bendpoint' && bendpointIndex - 1 === index) { var rel = relativePositionMidWaypoint(newWaypoints, bendpointIndex); if (rel < attachment.relativeLocation) { newIndex++; } } } return newIndex; } // start/end changed if (offset === 0) { return index; } if (hints.connectionStart) { return index === 0 ? 0 : null; } if (hints.connectionEnd) { return index === oldWaypoints.length - 2 ? newWaypoints.length - 2 : null; } // if nothing fits, return null return null; } /** * Calculate the required adjustment (move delta) for the given label * after the connection waypoints got updated. * * @param {djs.model.Label} label * @param {Array} newWaypoints * @param {Array} oldWaypoints * @param {Object} hints * * @return {Point} delta */ function getLabelAdjustment(label, newWaypoints, oldWaypoints, hints) { var x = 0, y = 0; var labelPosition = getLabelMid(label); // get closest attachment var attachment = (0, _LineAttachmentUtil.getAttachment)(labelPosition, oldWaypoints), oldLabelLineIndex = attachment.segmentIndex, newLabelLineIndex = findNewLabelLineStartIndex(oldWaypoints, newWaypoints, attachment, hints); if (newLabelLineIndex === null) { return { x: x, y: y }; } // should never happen // TODO(@janstuemmel): throw an error here when connectionSegmentMove is refactored if (newLabelLineIndex < 0 || newLabelLineIndex > newWaypoints.length - 2) { return { x: x, y: y }; } var oldLabelLine = getLine(oldWaypoints, oldLabelLineIndex), newLabelLine = getLine(newWaypoints, newLabelLineIndex), oldFoot = attachment.position; var relativeFootPosition = getRelativeFootPosition(oldLabelLine, oldFoot), angleDelta = getAngleDelta(oldLabelLine, newLabelLine); // special rule if label on bendpoint if (attachment.type === 'bendpoint') { var offset = newWaypoints.length - oldWaypoints.length, oldBendpointIndex = attachment.bendpointIndex, oldBendpoint = oldWaypoints[oldBendpointIndex]; // bendpoint position hasnt changed, return same position if (newWaypoints.indexOf(oldBendpoint) !== -1) { return { x: x, y: y }; } // new bendpoint and old bendpoint have same index, then just return the offset if (offset === 0) { var newBendpoint = newWaypoints[oldBendpointIndex]; return { x: newBendpoint.x - attachment.position.x, y: newBendpoint.y - attachment.position.y }; } // if bendpoints get removed if (offset < 0 && oldBendpointIndex !== 0 && oldBendpointIndex < oldWaypoints.length - 1) { relativeFootPosition = relativePositionMidWaypoint(oldWaypoints, oldBendpointIndex); } } var newFoot = { x: (newLabelLine[1].x - newLabelLine[0].x) * relativeFootPosition + newLabelLine[0].x, y: (newLabelLine[1].y - newLabelLine[0].y) * relativeFootPosition + newLabelLine[0].y }; // the rotated vector to label var newLabelVector = (0, _GeometricUtil.rotateVector)({ x: labelPosition.x - oldFoot.x, y: labelPosition.y - oldFoot.y }, angleDelta); // the new relative position x = newFoot.x + newLabelVector.x - labelPosition.x; y = newFoot.y + newLabelVector.y - labelPosition.y; return (0, _LayoutUtil.roundPoint)({ x: x, y: y }); } // HELPERS ////////////////////// function relativePositionMidWaypoint(waypoints, idx) { var distanceSegment1 = (0, _GeometricUtil.getDistancePointPoint)(waypoints[idx - 1], waypoints[idx]), distanceSegment2 = (0, _GeometricUtil.getDistancePointPoint)(waypoints[idx], waypoints[idx + 1]); var relativePosition = distanceSegment1 / (distanceSegment1 + distanceSegment2); return relativePosition; } function getLabelMid(label) { return { x: label.x + label.width / 2, y: label.y + label.height / 2 }; } function getAngleDelta(l1, l2) { var a1 = (0, _GeometricUtil.getAngle)(l1), a2 = (0, _GeometricUtil.getAngle)(l2); return a2 - a1; } function getLine(waypoints, idx) { return [waypoints[idx], waypoints[idx + 1]]; } function getRelativeFootPosition(line, foot) { var length = (0, _GeometricUtil.getDistancePointPoint)(line[0], line[1]), lengthToFoot = (0, _GeometricUtil.getDistancePointPoint)(line[0], foot); return length === 0 ? 0 : lengthToFoot / length; } },{"./GeometricUtil":174,"./LineAttachmentUtil":176,"diagram-js/lib/layout/LayoutUtil":380}],176:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAttachment = getAttachment; var sqrt = Math.sqrt, min = Math.min, max = Math.max, abs = Math.abs; /** * Calculate the square (power to two) of a number. * * @param {Number} n * * @return {Number} */ function sq(n) { return Math.pow(n, 2); } /** * Get distance between two points. * * @param {Point} p1 * @param {Point} p2 * * @return {Number} */ function getDistance(p1, p2) { return sqrt(sq(p1.x - p2.x) + sq(p1.y - p2.y)); } /** * Return the attachment of the given point on the specified line. * * The attachment is either a bendpoint (attached to the given point) * or segment (attached to a location on a line segment) attachment: * * ```javascript * var pointAttachment = { * type: 'bendpoint', * bendpointIndex: 3, * position: { x: 10, y: 10 } // the attach point on the line * }; * * var segmentAttachment = { * type: 'segment', * segmentIndex: 2, * relativeLocation: 0.31, // attach point location between 0 (at start) and 1 (at end) * position: { x: 10, y: 10 } // the attach point on the line * }; * ``` * * @param {Point} point * @param {Array} line * * @return {Object} attachment */ function getAttachment(point, line) { var idx = 0, segmentStart, segmentEnd, segmentStartDistance, segmentEndDistance, attachmentPosition, minDistance, intersections, attachment, attachmentDistance, closestAttachmentDistance, closestAttachment; for (idx = 0; idx < line.length - 1; idx++) { segmentStart = line[idx]; segmentEnd = line[idx + 1]; if (pointsEqual(segmentStart, segmentEnd)) { intersections = [segmentStart]; } else { segmentStartDistance = getDistance(point, segmentStart); segmentEndDistance = getDistance(point, segmentEnd); minDistance = min(segmentStartDistance, segmentEndDistance); intersections = getCircleSegmentIntersections(segmentStart, segmentEnd, point, minDistance); } if (intersections.length < 1) { throw new Error('expected between [1, 2] circle -> line intersections'); } // one intersection -> bendpoint attachment if (intersections.length === 1) { attachment = { type: 'bendpoint', position: intersections[0], segmentIndex: idx, bendpointIndex: pointsEqual(segmentStart, intersections[0]) ? idx : idx + 1 }; } // two intersections -> segment attachment if (intersections.length === 2) { attachmentPosition = mid(intersections[0], intersections[1]); attachment = { type: 'segment', position: attachmentPosition, segmentIndex: idx, relativeLocation: getDistance(segmentStart, attachmentPosition) / getDistance(segmentStart, segmentEnd) }; } attachmentDistance = getDistance(attachment.position, point); if (!closestAttachment || closestAttachmentDistance > attachmentDistance) { closestAttachment = attachment; closestAttachmentDistance = attachmentDistance; } } return closestAttachment; } /** * Gets the intersection between a circle and a line segment. * * @param {Point} s1 segment start * @param {Point} s2 segment end * @param {Point} cc circle center * @param {Number} cr circle radius * * @return {Array} intersections */ function getCircleSegmentIntersections(s1, s2, cc, cr) { var baX = s2.x - s1.x; var baY = s2.y - s1.y; var caX = cc.x - s1.x; var caY = cc.y - s1.y; var a = baX * baX + baY * baY; var bBy2 = baX * caX + baY * caY; var c = caX * caX + caY * caY - cr * cr; var pBy2 = bBy2 / a; var q = c / a; var disc = pBy2 * pBy2 - q; // check against negative value to work around // negative, very close to zero results (-4e-15) // being produced in some environments if (disc < 0 && disc > -0.000001) { disc = 0; } if (disc < 0) { return []; } // if disc == 0 ... dealt with later var tmpSqrt = sqrt(disc); var abScalingFactor1 = -pBy2 + tmpSqrt; var abScalingFactor2 = -pBy2 - tmpSqrt; var i1 = { x: s1.x - baX * abScalingFactor1, y: s1.y - baY * abScalingFactor1 }; if (disc === 0) { // abScalingFactor1 == abScalingFactor2 return [i1]; } var i2 = { x: s1.x - baX * abScalingFactor2, y: s1.y - baY * abScalingFactor2 }; // return only points on line segment return [i1, i2].filter(function (p) { return isPointInSegment(p, s1, s2); }); } function isPointInSegment(p, segmentStart, segmentEnd) { return fenced(p.x, segmentStart.x, segmentEnd.x) && fenced(p.y, segmentStart.y, segmentEnd.y); } function fenced(n, rangeStart, rangeEnd) { // use matching threshold to work around // precisison errors in intersection computation return n >= min(rangeStart, rangeEnd) - EQUAL_THRESHOLD && n <= max(rangeStart, rangeEnd) + EQUAL_THRESHOLD; } /** * Calculate mid of two points. * * @param {Point} p1 * @param {Point} p2 * * @return {Point} */ function mid(p1, p2) { return { x: (p1.x + p2.x) / 2, y: (p1.y + p2.y) / 2 }; } var EQUAL_THRESHOLD = 0.1; function pointsEqual(p1, p2) { return abs(p1.x - p2.x) <= EQUAL_THRESHOLD && abs(p1.y - p2.y) <= EQUAL_THRESHOLD; } },{}],177:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = lineIntersect; /** * Returns the intersection between two line segments a and b. * * @param {Point} l1s * @param {Point} l1e * @param {Point} l2s * @param {Point} l2e * * @return {Point} */ function lineIntersect(l1s, l1e, l2s, l2e) { // if the lines intersect, the result contains the x and y of the // intersection (treating the lines as infinite) and booleans for // whether line segment 1 or line segment 2 contain the point var denominator, a, b, c, numerator; denominator = (l2e.y - l2s.y) * (l1e.x - l1s.x) - (l2e.x - l2s.x) * (l1e.y - l1s.y); if (denominator == 0) { return null; } a = l1s.y - l2s.y; b = l1s.x - l2s.x; numerator = (l2e.x - l2s.x) * a - (l2e.y - l2s.y) * b; c = numerator / denominator; // if we cast these lines infinitely in // both directions, they intersect here return { x: Math.round(l1s.x + c * (l1e.x - l1s.x)), y: Math.round(l1s.y + c * (l1e.y - l1s.y)) }; } },{}],178:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AddLaneHandler; var _minDash = require('min-dash'); var _Elements = require('diagram-js/lib/util/Elements'); var _LaneUtil = require('../util/LaneUtil'); /** * A handler that allows us to add a new lane * above or below an existing one. * * @param {Modeling} modeling */ function AddLaneHandler(modeling, spaceTool) { this._modeling = modeling; this._spaceTool = spaceTool; } AddLaneHandler.$inject = ['modeling', 'spaceTool']; AddLaneHandler.prototype.preExecute = function (context) { var spaceTool = this._spaceTool, modeling = this._modeling; var shape = context.shape, location = context.location; var lanesRoot = (0, _LaneUtil.getLanesRoot)(shape); var isRoot = lanesRoot === shape, laneParent = isRoot ? shape : shape.parent; var existingChildLanes = (0, _LaneUtil.getChildLanes)(laneParent); // (0) add a lane if we currently got none and are adding to root if (!existingChildLanes.length) { modeling.createShape({ type: 'bpmn:Lane' }, { x: shape.x + _LaneUtil.LANE_INDENTATION, y: shape.y, width: shape.width - _LaneUtil.LANE_INDENTATION, height: shape.height }, laneParent); } // (1) collect affected elements to create necessary space var allAffected = []; (0, _Elements.eachElement)(lanesRoot, function (element) { allAffected.push(element); if (element === shape) { return []; } return (0, _minDash.filter)(element.children, function (c) { return c !== shape; }); }); var offset = location === 'top' ? -120 : 120, lanePosition = location === 'top' ? shape.y : shape.y + shape.height, spacePos = lanePosition + (location === 'top' ? 10 : -10), direction = location === 'top' ? 'n' : 's'; var adjustments = spaceTool.calculateAdjustments(allAffected, 'y', offset, spacePos); spaceTool.makeSpace(adjustments.movingShapes, adjustments.resizingShapes, { x: 0, y: offset }, direction); // (2) create new lane at open space context.newLane = modeling.createShape({ type: 'bpmn:Lane' }, { x: shape.x + (isRoot ? _LaneUtil.LANE_INDENTATION : 0), y: lanePosition - (location === 'top' ? 120 : 0), width: shape.width - (isRoot ? _LaneUtil.LANE_INDENTATION : 0), height: 120 }, laneParent); }; },{"../util/LaneUtil":188,"diagram-js/lib/util/Elements":396,"min-dash":505}],179:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = IdClaimHandler; function IdClaimHandler(moddle) { this._moddle = moddle; } IdClaimHandler.$inject = ['moddle']; IdClaimHandler.prototype.execute = function (context) { var ids = this._moddle.ids, id = context.id, element = context.element, claiming = context.claiming; if (claiming) { ids.claim(id, element); } else { ids.unclaim(id); } }; /** * Command revert implementation. */ IdClaimHandler.prototype.revert = function (context) { var ids = this._moddle.ids, id = context.id, element = context.element, claiming = context.claiming; if (claiming) { ids.unclaim(id); } else { ids.claim(id, element); } }; },{}],180:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ResizeLaneHandler; var _ModelUtil = require('../../../util/ModelUtil'); var _LaneUtil = require('../util/LaneUtil'); var _Elements = require('diagram-js/lib/util/Elements'); var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil'); var _ResizeUtil = require('diagram-js/lib/features/resize/ResizeUtil'); /** * A handler that resizes a lane. * * @param {Modeling} modeling */ function ResizeLaneHandler(modeling, spaceTool) { this._modeling = modeling; this._spaceTool = spaceTool; } ResizeLaneHandler.$inject = ['modeling', 'spaceTool']; ResizeLaneHandler.prototype.preExecute = function (context) { var shape = context.shape, newBounds = context.newBounds, balanced = context.balanced; if (balanced !== false) { this.resizeBalanced(shape, newBounds); } else { this.resizeSpace(shape, newBounds); } }; /** * Resize balanced, adjusting next / previous lane sizes. * * @param {djs.model.Shape} shape * @param {Bounds} newBounds */ ResizeLaneHandler.prototype.resizeBalanced = function (shape, newBounds) { var modeling = this._modeling; var resizeNeeded = (0, _LaneUtil.computeLanesResize)(shape, newBounds); // resize the lane modeling.resizeShape(shape, newBounds); // resize other lanes as needed resizeNeeded.forEach(function (r) { modeling.resizeShape(r.shape, r.newBounds); }); }; /** * Resize, making actual space and moving below / above elements. * * @param {djs.model.Shape} shape * @param {Bounds} newBounds */ ResizeLaneHandler.prototype.resizeSpace = function (shape, newBounds) { var spaceTool = this._spaceTool; var shapeTrbl = (0, _LayoutUtil.asTRBL)(shape), newTrbl = (0, _LayoutUtil.asTRBL)(newBounds); var trblDiff = (0, _ResizeUtil.substractTRBL)(newTrbl, shapeTrbl); var lanesRoot = (0, _LaneUtil.getLanesRoot)(shape); var allAffected = [], allLanes = []; (0, _Elements.eachElement)(lanesRoot, function (element) { allAffected.push(element); if ((0, _ModelUtil.is)(element, 'bpmn:Lane') || (0, _ModelUtil.is)(element, 'bpmn:Participant')) { allLanes.push(element); } return element.children; }); var change, spacePos, direction, offset, adjustments; if (trblDiff.bottom || trblDiff.top) { change = trblDiff.bottom || trblDiff.top; spacePos = shape.y + (trblDiff.bottom ? shape.height : 0) + (trblDiff.bottom ? -10 : 10); direction = trblDiff.bottom ? 's' : 'n'; offset = trblDiff.top > 0 || trblDiff.bottom < 0 ? -change : change; adjustments = spaceTool.calculateAdjustments(allAffected, 'y', offset, spacePos); spaceTool.makeSpace(adjustments.movingShapes, adjustments.resizingShapes, { x: 0, y: change }, direction); } if (trblDiff.left || trblDiff.right) { change = trblDiff.right || trblDiff.left; spacePos = shape.x + (trblDiff.right ? shape.width : 0) + (trblDiff.right ? -10 : 100); direction = trblDiff.right ? 'e' : 'w'; offset = trblDiff.left > 0 || trblDiff.right < 0 ? -change : change; adjustments = spaceTool.calculateAdjustments(allLanes, 'x', offset, spacePos); spaceTool.makeSpace(adjustments.movingShapes, adjustments.resizingShapes, { x: change, y: 0 }, direction); } }; },{"../../../util/ModelUtil":216,"../util/LaneUtil":188,"diagram-js/lib/features/resize/ResizeUtil":351,"diagram-js/lib/layout/LayoutUtil":380,"diagram-js/lib/util/Elements":396}],181:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SetColorHandler; var _minDash = require('min-dash'); var DEFAULT_COLORS = { fill: undefined, stroke: undefined }; function SetColorHandler(commandStack) { this._commandStack = commandStack; } SetColorHandler.$inject = ['commandStack']; SetColorHandler.prototype.postExecute = function (context) { var elements = context.elements, colors = context.colors || DEFAULT_COLORS; var self = this; var di = {}; if ('fill' in colors) { (0, _minDash.assign)(di, { fill: colors.fill }); } if ('stroke' in colors) { (0, _minDash.assign)(di, { stroke: colors.stroke }); } (0, _minDash.forEach)(elements, function (element) { self._commandStack.execute('element.updateProperties', { element: element, properties: { di: di } }); }); }; },{"min-dash":505}],182:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SplitLaneHandler; var _LaneUtil = require('../util/LaneUtil'); /** * A handler that splits a lane into a number of sub-lanes, * creating new sub lanes, if neccessary. * * @param {Modeling} modeling */ function SplitLaneHandler(modeling, translate) { this._modeling = modeling; this._translate = translate; } SplitLaneHandler.$inject = ['modeling', 'translate']; SplitLaneHandler.prototype.preExecute = function (context) { var modeling = this._modeling, translate = this._translate; var shape = context.shape, newLanesCount = context.count; var childLanes = (0, _LaneUtil.getChildLanes)(shape), existingLanesCount = childLanes.length; if (existingLanesCount > newLanesCount) { throw new Error(translate('more than {count} child lanes', { count: newLanesCount })); } var newLanesHeight = Math.round(shape.height / newLanesCount); // Iterate from top to bottom in child lane order, // resizing existing lanes and creating new ones // so that they split the parent proportionally. // // Due to rounding related errors, the bottom lane // needs to take up all the remaining space. var laneY, laneHeight, laneBounds, newLaneAttrs, idx; for (idx = 0; idx < newLanesCount; idx++) { laneY = shape.y + idx * newLanesHeight; // if bottom lane if (idx === newLanesCount - 1) { laneHeight = shape.height - newLanesHeight * idx; } else { laneHeight = newLanesHeight; } laneBounds = { x: shape.x + _LaneUtil.LANE_INDENTATION, y: laneY, width: shape.width - _LaneUtil.LANE_INDENTATION, height: laneHeight }; if (idx < existingLanesCount) { // resize existing lane modeling.resizeShape(childLanes[idx], laneBounds); } else { // create a new lane at position newLaneAttrs = { type: 'bpmn:Lane' }; modeling.createShape(newLaneAttrs, laneBounds, shape); } } }; },{"../util/LaneUtil":188}],183:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UpdateCanvasRootHandler; var _Collections = require('diagram-js/lib/util/Collections'); function UpdateCanvasRootHandler(canvas, modeling) { this._canvas = canvas; this._modeling = modeling; } UpdateCanvasRootHandler.$inject = ['canvas', 'modeling']; UpdateCanvasRootHandler.prototype.execute = function (context) { var canvas = this._canvas; var newRoot = context.newRoot, newRootBusinessObject = newRoot.businessObject, oldRoot = canvas.getRootElement(), oldRootBusinessObject = oldRoot.businessObject, bpmnDefinitions = oldRootBusinessObject.$parent, diPlane = oldRootBusinessObject.di; // (1) replace process old <> new root canvas.setRootElement(newRoot, true); // (2) update root elements (0, _Collections.add)(bpmnDefinitions.rootElements, newRootBusinessObject); newRootBusinessObject.$parent = bpmnDefinitions; (0, _Collections.remove)(bpmnDefinitions.rootElements, oldRootBusinessObject); oldRootBusinessObject.$parent = null; // (3) wire di oldRootBusinessObject.di = null; diPlane.bpmnElement = newRootBusinessObject; newRootBusinessObject.di = diPlane; context.oldRoot = oldRoot; // TODO(nikku): return changed elements? // return [ newRoot, oldRoot ]; }; UpdateCanvasRootHandler.prototype.revert = function (context) { var canvas = this._canvas; var newRoot = context.newRoot, newRootBusinessObject = newRoot.businessObject, oldRoot = context.oldRoot, oldRootBusinessObject = oldRoot.businessObject, bpmnDefinitions = newRootBusinessObject.$parent, diPlane = newRootBusinessObject.di; // (1) replace process old <> new root canvas.setRootElement(oldRoot, true); // (2) update root elements (0, _Collections.remove)(bpmnDefinitions.rootElements, newRootBusinessObject); newRootBusinessObject.$parent = null; (0, _Collections.add)(bpmnDefinitions.rootElements, oldRootBusinessObject); oldRootBusinessObject.$parent = bpmnDefinitions; // (3) wire di newRootBusinessObject.di = null; diPlane.bpmnElement = oldRootBusinessObject; oldRootBusinessObject.di = diPlane; // TODO(nikku): return changed elements? // return [ newRoot, oldRoot ]; }; },{"diagram-js/lib/util/Collections":393}],184:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UpdateFlowNodeRefsHandler; var _LaneUtil = require('../util/LaneUtil'); var _ModelUtil = require('../../../util/ModelUtil'); var _Collections = require('diagram-js/lib/util/Collections'); var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil'); var FLOW_NODE_REFS_ATTR = 'flowNodeRef', LANES_ATTR = 'lanes'; /** * A handler that updates lane refs on changed elements */ function UpdateFlowNodeRefsHandler(elementRegistry) { this._elementRegistry = elementRegistry; } UpdateFlowNodeRefsHandler.$inject = ['elementRegistry']; UpdateFlowNodeRefsHandler.prototype.computeUpdates = function (flowNodeShapes, laneShapes) { var handledNodes = {}; var updates = []; var participantCache = {}; var allFlowNodeShapes = []; function isInLaneShape(element, laneShape) { var laneTrbl = (0, _LayoutUtil.asTRBL)(laneShape); var elementMid = { x: element.x + element.width / 2, y: element.y + element.height / 2 }; return elementMid.x > laneTrbl.left && elementMid.x < laneTrbl.right && elementMid.y > laneTrbl.top && elementMid.y < laneTrbl.bottom; } function addFlowNodeShape(flowNodeShape) { if (!handledNodes[flowNodeShape.id]) { allFlowNodeShapes.push(flowNodeShape); handledNodes[flowNodeShape.id] = flowNodeShape; } } function getAllLaneShapes(flowNodeShape) { var root = (0, _LaneUtil.getLanesRoot)(flowNodeShape); if (!participantCache[root.id]) { participantCache[root.id] = (0, _LaneUtil.collectLanes)(root); } return participantCache[root.id]; } function getNewLanes(flowNodeShape) { if (!flowNodeShape.parent) { return []; } var allLaneShapes = getAllLaneShapes(flowNodeShape); return allLaneShapes.filter(function (l) { return isInLaneShape(flowNodeShape, l); }).map(function (shape) { return shape.businessObject; }); } laneShapes.forEach(function (laneShape) { var root = (0, _LaneUtil.getLanesRoot)(laneShape); if (!root || handledNodes[root.id]) { return; } var children = root.children.filter(function (c) { return (0, _ModelUtil.is)(c, 'bpmn:FlowNode'); }); children.forEach(addFlowNodeShape); handledNodes[root.id] = root; }); flowNodeShapes.forEach(addFlowNodeShape); allFlowNodeShapes.forEach(function (flowNodeShape) { var flowNode = flowNodeShape.businessObject; var lanes = flowNode.get(LANES_ATTR), remove = lanes.slice(), add = getNewLanes(flowNodeShape); updates.push({ flowNode: flowNode, remove: remove, add: add }); }); laneShapes.forEach(function (laneShape) { var lane = laneShape.businessObject; // lane got removed XX-) if (!laneShape.parent) { lane.get(FLOW_NODE_REFS_ATTR).forEach(function (flowNode) { updates.push({ flowNode: flowNode, remove: [lane], add: [] }); }); } }); return updates; }; UpdateFlowNodeRefsHandler.prototype.execute = function (context) { var updates = context.updates; if (!updates) { updates = context.updates = this.computeUpdates(context.flowNodeShapes, context.laneShapes); } updates.forEach(function (update) { var flowNode = update.flowNode, lanes = flowNode.get(LANES_ATTR); // unwire old update.remove.forEach(function (oldLane) { (0, _Collections.remove)(lanes, oldLane); (0, _Collections.remove)(oldLane.get(FLOW_NODE_REFS_ATTR), flowNode); }); // wire new update.add.forEach(function (newLane) { (0, _Collections.add)(lanes, newLane); (0, _Collections.add)(newLane.get(FLOW_NODE_REFS_ATTR), flowNode); }); }); // TODO(nikku): return changed elements // return [ ... ]; }; UpdateFlowNodeRefsHandler.prototype.revert = function (context) { var updates = context.updates; updates.forEach(function (update) { var flowNode = update.flowNode, lanes = flowNode.get(LANES_ATTR); // unwire new update.add.forEach(function (newLane) { (0, _Collections.remove)(lanes, newLane); (0, _Collections.remove)(newLane.get(FLOW_NODE_REFS_ATTR), flowNode); }); // wire old update.remove.forEach(function (oldLane) { (0, _Collections.add)(lanes, oldLane); (0, _Collections.add)(oldLane.get(FLOW_NODE_REFS_ATTR), flowNode); }); }); // TODO(nikku): return changed elements // return [ ... ]; }; },{"../../../util/ModelUtil":216,"../util/LaneUtil":188,"diagram-js/lib/layout/LayoutUtil":380,"diagram-js/lib/util/Collections":393}],185:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UpdatePropertiesHandler; var _minDash = require('min-dash'); var _ModelUtil = require('../../../util/ModelUtil'); var DEFAULT_FLOW = 'default', ID = 'id', DI = 'di'; var NULL_DIMENSIONS = { width: 0, height: 0 }; /** * A handler that implements a BPMN 2.0 property update. * * This should be used to set simple properties on elements with * an underlying BPMN business object. * * Use respective diagram-js provided handlers if you would * like to perform automated modeling. */ function UpdatePropertiesHandler(elementRegistry, moddle, translate, modeling, textRenderer) { this._elementRegistry = elementRegistry; this._moddle = moddle; this._translate = translate; this._modeling = modeling; this._textRenderer = textRenderer; } UpdatePropertiesHandler.$inject = ['elementRegistry', 'moddle', 'translate', 'modeling', 'textRenderer']; // api ////////////////////// /** * Updates a BPMN element with a list of new properties * * @param {Object} context * @param {djs.model.Base} context.element the element to update * @param {Object} context.properties a list of properties to set on the element's * businessObject (the BPMN model element) * * @return {Array} the updated element */ UpdatePropertiesHandler.prototype.execute = function (context) { var element = context.element, changed = [element], translate = this._translate; if (!element) { throw new Error(translate('element required')); } var elementRegistry = this._elementRegistry, ids = this._moddle.ids; var businessObject = element.businessObject, properties = unwrapBusinessObjects(context.properties), oldProperties = context.oldProperties || getProperties(businessObject, properties); if (isIdChange(properties, businessObject)) { ids.unclaim(businessObject[ID]); elementRegistry.updateId(element, properties[ID]); ids.claim(properties[ID], businessObject); } // correctly indicate visual changes on default flow updates if (DEFAULT_FLOW in properties) { if (properties[DEFAULT_FLOW]) { changed.push(elementRegistry.get(properties[DEFAULT_FLOW].id)); } if (businessObject[DEFAULT_FLOW]) { changed.push(elementRegistry.get(businessObject[DEFAULT_FLOW].id)); } } // update properties setProperties(businessObject, properties); // store old values context.oldProperties = oldProperties; context.changed = changed; // indicate changed on objects affected by the update return changed; }; UpdatePropertiesHandler.prototype.postExecute = function (context) { var element = context.element, label = element.label; var text = label && (0, _ModelUtil.getBusinessObject)(label).name; if (!text) { return; } // get layouted text bounds and resize external // external label accordingly var newLabelBounds = this._textRenderer.getExternalLabelBounds(label, text); this._modeling.resizeShape(label, newLabelBounds, NULL_DIMENSIONS); }; /** * Reverts the update on a BPMN elements properties. * * @param {Object} context * * @return {djs.model.Base} the updated element */ UpdatePropertiesHandler.prototype.revert = function (context) { var element = context.element, properties = context.properties, oldProperties = context.oldProperties, businessObject = element.businessObject, elementRegistry = this._elementRegistry, ids = this._moddle.ids; // update properties setProperties(businessObject, oldProperties); if (isIdChange(properties, businessObject)) { ids.unclaim(properties[ID]); elementRegistry.updateId(element, oldProperties[ID]); ids.claim(oldProperties[ID], businessObject); } return context.changed; }; function isIdChange(properties, businessObject) { return ID in properties && properties[ID] !== businessObject[ID]; } function getProperties(businessObject, properties) { var propertyNames = (0, _minDash.keys)(properties); return (0, _minDash.reduce)(propertyNames, function (result, key) { // handle DI seperately if (key !== DI) { result[key] = businessObject.get(key); } else { result[key] = getDiProperties(businessObject.di, (0, _minDash.keys)(properties.di)); } return result; }, {}); } function getDiProperties(di, propertyNames) { return (0, _minDash.reduce)(propertyNames, function (result, key) { result[key] = di.get(key); return result; }, {}); } function setProperties(businessObject, properties) { (0, _minDash.forEach)(properties, function (value, key) { if (key !== DI) { businessObject.set(key, value); } else { // only update, if businessObject.di exists if (businessObject.di) { setDiProperties(businessObject.di, value); } } }); } function setDiProperties(di, properties) { (0, _minDash.forEach)(properties, function (value, key) { di.set(key, value); }); } var referencePropertyNames = ['default']; /** * Make sure we unwrap the actual business object * behind diagram element that may have been * passed as arguments. * * @param {Object} properties * * @return {Object} unwrappedProps */ function unwrapBusinessObjects(properties) { var unwrappedProps = (0, _minDash.assign)({}, properties); referencePropertyNames.forEach(function (name) { if (name in properties) { unwrappedProps[name] = (0, _ModelUtil.getBusinessObject)(unwrappedProps[name]); } }); return unwrappedProps; } },{"../../../util/ModelUtil":216,"min-dash":505}],186:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UpdateSemanticParentHandler; function UpdateSemanticParentHandler(bpmnUpdater) { this._bpmnUpdater = bpmnUpdater; } UpdateSemanticParentHandler.$inject = ['bpmnUpdater']; UpdateSemanticParentHandler.prototype.execute = function (context) { var dataStoreBo = context.dataStoreBo, newSemanticParent = context.newSemanticParent, newDiParent = context.newDiParent; context.oldSemanticParent = dataStoreBo.$parent; context.oldDiParent = dataStoreBo.di.$parent; // update semantic parent this._bpmnUpdater.updateSemanticParent(dataStoreBo, newSemanticParent); // update DI parent this._bpmnUpdater.updateDiParent(dataStoreBo.di, newDiParent); }; UpdateSemanticParentHandler.prototype.revert = function (context) { var dataStoreBo = context.dataStoreBo, oldSemanticParent = context.oldSemanticParent, oldDiParent = context.oldDiParent; // update semantic parent this._bpmnUpdater.updateSemanticParent(dataStoreBo, oldSemanticParent); // update DI parent this._bpmnUpdater.updateDiParent(dataStoreBo.di, oldDiParent); }; },{}],187:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _behavior = require('./behavior'); var _behavior2 = _interopRequireDefault(_behavior); var _rules = require('../rules'); var _rules2 = _interopRequireDefault(_rules); var _ordering = require('../ordering'); var _ordering2 = _interopRequireDefault(_ordering); var _replace = require('../replace'); var _replace2 = _interopRequireDefault(_replace); var _command = require('diagram-js/lib/command'); var _command2 = _interopRequireDefault(_command); var _tooltips = require('diagram-js/lib/features/tooltips'); var _tooltips2 = _interopRequireDefault(_tooltips); var _labelSupport = require('diagram-js/lib/features/label-support'); var _labelSupport2 = _interopRequireDefault(_labelSupport); var _attachSupport = require('diagram-js/lib/features/attach-support'); var _attachSupport2 = _interopRequireDefault(_attachSupport); var _selection = require('diagram-js/lib/features/selection'); var _selection2 = _interopRequireDefault(_selection); var _changeSupport = require('diagram-js/lib/features/change-support'); var _changeSupport2 = _interopRequireDefault(_changeSupport); var _spaceTool = require('diagram-js/lib/features/space-tool'); var _spaceTool2 = _interopRequireDefault(_spaceTool); var _BpmnFactory = require('./BpmnFactory'); var _BpmnFactory2 = _interopRequireDefault(_BpmnFactory); var _BpmnUpdater = require('./BpmnUpdater'); var _BpmnUpdater2 = _interopRequireDefault(_BpmnUpdater); var _ElementFactory = require('./ElementFactory'); var _ElementFactory2 = _interopRequireDefault(_ElementFactory); var _Modeling = require('./Modeling'); var _Modeling2 = _interopRequireDefault(_Modeling); var _BpmnLayouter = require('./BpmnLayouter'); var _BpmnLayouter2 = _interopRequireDefault(_BpmnLayouter); var _CroppingConnectionDocking = require('diagram-js/lib/layout/CroppingConnectionDocking'); var _CroppingConnectionDocking2 = _interopRequireDefault(_CroppingConnectionDocking); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['modeling', 'bpmnUpdater'], __depends__: [_behavior2.default, _rules2.default, _ordering2.default, _replace2.default, _command2.default, _tooltips2.default, _labelSupport2.default, _attachSupport2.default, _selection2.default, _changeSupport2.default, _spaceTool2.default], bpmnFactory: ['type', _BpmnFactory2.default], bpmnUpdater: ['type', _BpmnUpdater2.default], elementFactory: ['type', _ElementFactory2.default], modeling: ['type', _Modeling2.default], layouter: ['type', _BpmnLayouter2.default], connectionDocking: ['type', _CroppingConnectionDocking2.default] }; },{"../ordering":191,"../replace":201,"../rules":203,"./BpmnFactory":145,"./BpmnLayouter":146,"./BpmnUpdater":147,"./ElementFactory":148,"./Modeling":149,"./behavior":173,"diagram-js/lib/command":245,"diagram-js/lib/features/attach-support":259,"diagram-js/lib/features/change-support":271,"diagram-js/lib/features/label-support":302,"diagram-js/lib/features/selection":361,"diagram-js/lib/features/space-tool":368,"diagram-js/lib/features/tooltips":372,"diagram-js/lib/layout/CroppingConnectionDocking":379}],188:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.LANE_INDENTATION = undefined; exports.collectLanes = collectLanes; exports.getChildLanes = getChildLanes; exports.getLanesRoot = getLanesRoot; exports.computeLanesResize = computeLanesResize; var _ModelUtil = require('../../../util/ModelUtil'); var _ModelingUtil = require('./ModelingUtil'); var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil'); var _ResizeUtil = require('diagram-js/lib/features/resize/ResizeUtil'); var abs = Math.abs; function getTRBLResize(oldBounds, newBounds) { return (0, _ResizeUtil.substractTRBL)((0, _LayoutUtil.asTRBL)(newBounds), (0, _LayoutUtil.asTRBL)(oldBounds)); } var LANE_PARENTS = ['bpmn:Participant', 'bpmn:Process', 'bpmn:SubProcess']; var LANE_INDENTATION = exports.LANE_INDENTATION = 30; /** * Collect all lane shapes in the given paren * * @param {djs.model.Shape} shape * @param {Array} [collectedShapes] * * @return {Array} */ function collectLanes(shape, collectedShapes) { collectedShapes = collectedShapes || []; shape.children.filter(function (s) { if ((0, _ModelUtil.is)(s, 'bpmn:Lane')) { collectLanes(s, collectedShapes); collectedShapes.push(s); } }); return collectedShapes; } /** * Return the lane children of the given element. * * @param {djs.model.Shape} shape * * @return {Array} */ function getChildLanes(shape) { return shape.children.filter(function (c) { return (0, _ModelUtil.is)(c, 'bpmn:Lane'); }); } /** * Return the root element containing the given lane shape * * @param {djs.model.Shape} shape * * @return {djs.model.Shape} */ function getLanesRoot(shape) { return (0, _ModelingUtil.getParent)(shape, LANE_PARENTS) || shape; } /** * Compute the required resize operations for lanes * adjacent to the given shape, assuming it will be * resized to the given new bounds. * * @param {djs.model.Shape} shape * @param {Bounds} newBounds * * @return {Array} */ function computeLanesResize(shape, newBounds) { var rootElement = getLanesRoot(shape); var initialShapes = (0, _ModelUtil.is)(rootElement, 'bpmn:Process') ? [] : [rootElement]; var allLanes = collectLanes(rootElement, initialShapes), shapeTrbl = (0, _LayoutUtil.asTRBL)(shape), shapeNewTrbl = (0, _LayoutUtil.asTRBL)(newBounds), trblResize = getTRBLResize(shape, newBounds), resizeNeeded = []; allLanes.forEach(function (other) { if (other === shape) { return; } var topResize = 0, rightResize = trblResize.right, bottomResize = 0, leftResize = trblResize.left; var otherTrbl = (0, _LayoutUtil.asTRBL)(other); if (trblResize.top) { if (abs(otherTrbl.bottom - shapeTrbl.top) < 10) { bottomResize = shapeNewTrbl.top - otherTrbl.bottom; } if (abs(otherTrbl.top - shapeTrbl.top) < 5) { topResize = shapeNewTrbl.top - otherTrbl.top; } } if (trblResize.bottom) { if (abs(otherTrbl.top - shapeTrbl.bottom) < 10) { topResize = shapeNewTrbl.bottom - otherTrbl.top; } if (abs(otherTrbl.bottom - shapeTrbl.bottom) < 5) { bottomResize = shapeNewTrbl.bottom - otherTrbl.bottom; } } if (topResize || rightResize || bottomResize || leftResize) { resizeNeeded.push({ shape: other, newBounds: (0, _ResizeUtil.resizeTRBL)(other, { top: topResize, right: rightResize, bottom: bottomResize, left: leftResize }) }); } }); return resizeNeeded; } },{"../../../util/ModelUtil":216,"./ModelingUtil":189,"diagram-js/lib/features/resize/ResizeUtil":351,"diagram-js/lib/layout/LayoutUtil":380}],189:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.isAny = isAny; exports.getParent = getParent; var _minDash = require('min-dash'); var _ModelUtil = require('../../../util/ModelUtil'); /** * Return true if element has any of the given types. * * @param {djs.model.Base} element * @param {Array} types * * @return {Boolean} */ function isAny(element, types) { return (0, _minDash.some)(types, function (t) { return (0, _ModelUtil.is)(element, t); }); } /** * Return the parent of the element with any of the given types. * * @param {djs.model.Base} element * @param {String|Array} anyType * * @return {djs.model.Base} */ function getParent(element, anyType) { if (typeof anyType === 'string') { anyType = [anyType]; } while (element = element.parent) { if (isAny(element, anyType)) { return element; } } return null; } },{"../../../util/ModelUtil":216,"min-dash":505}],190:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnOrderingProvider; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _OrderingProvider = require('diagram-js/lib/features/ordering/OrderingProvider'); var _OrderingProvider2 = _interopRequireDefault(_OrderingProvider); var _ModelingUtil = require('../modeling/util/ModelingUtil'); var _minDash = require('min-dash'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * a simple ordering provider that makes sure: * * (0) labels are rendered always on top * (1) elements are ordered by a {level} property */ function BpmnOrderingProvider(eventBus, canvas, translate) { _OrderingProvider2.default.call(this, eventBus); var orders = [{ type: 'bpmn:SubProcess', order: { level: 6 } }, { type: 'bpmn:SequenceFlow', order: { level: 3, containers: ['bpmn:Participant', 'bpmn:FlowElementsContainer'] } }, // handle DataAssociation(s) like message flows and render them always on top { type: 'bpmn:DataAssociation', order: { level: 9, containers: ['bpmn:Collaboration', 'bpmn:Process'] } }, { type: 'bpmn:MessageFlow', order: { level: 9, containers: ['bpmn:Collaboration'] } }, { type: 'bpmn:Association', order: { level: 6, containers: ['bpmn:Participant', 'bpmn:FlowElementsContainer', 'bpmn:Collaboration'] } }, { type: 'bpmn:BoundaryEvent', order: { level: 8 } }, { type: 'bpmn:FlowElement', order: { level: 5 } }, { type: 'bpmn:Participant', order: { level: -2 } }, { type: 'bpmn:Lane', order: { level: -1 } }]; function computeOrder(element) { if (element.labelTarget) { return { level: 10 }; } var entry = (0, _minDash.find)(orders, function (o) { return (0, _ModelingUtil.isAny)(element, [o.type]); }); return entry && entry.order || { level: 1 }; } function getOrder(element) { var order = element.order; if (!order) { element.order = order = computeOrder(element); } return order; } function findActualParent(element, newParent, containers) { var actualParent = newParent; while (actualParent) { if ((0, _ModelingUtil.isAny)(actualParent, containers)) { break; } actualParent = actualParent.parent; } if (!actualParent) { throw new Error(translate('no parent for {element} in {parent}', { element: element.id, parent: newParent.id })); } return actualParent; } this.getOrdering = function (element, newParent) { // render labels always on top if (element.labelTarget) { return { parent: canvas.getRootElement(), index: -1 }; } var elementOrder = getOrder(element); if (elementOrder.containers) { newParent = findActualParent(element, newParent, elementOrder.containers); } var currentIndex = newParent.children.indexOf(element); var insertIndex = (0, _minDash.findIndex)(newParent.children, function (child) { // do not compare with labels, they are created // in the wrong order (right after elements) during import and // mess up the positioning. if (!element.labelTarget && child.labelTarget) { return false; } return elementOrder.level < getOrder(child).level; }); // if the element is already in the child list at // a smaller index, we need to adjust the inser index. // this takes into account that the element is being removed // before being re-inserted if (insertIndex !== -1) { if (currentIndex !== -1 && currentIndex < insertIndex) { insertIndex -= 1; } } return { index: insertIndex, parent: newParent }; }; } BpmnOrderingProvider.$inject = ['eventBus', 'canvas', 'translate']; (0, _inherits2.default)(BpmnOrderingProvider, _OrderingProvider2.default); },{"../modeling/util/ModelingUtil":189,"diagram-js/lib/features/ordering/OrderingProvider":335,"inherits":415,"min-dash":505}],191:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _translate = require('diagram-js/lib/i18n/translate'); var _translate2 = _interopRequireDefault(_translate); var _BpmnOrderingProvider = require('./BpmnOrderingProvider'); var _BpmnOrderingProvider2 = _interopRequireDefault(_BpmnOrderingProvider); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_translate2.default], __init__: ['bpmnOrderingProvider'], bpmnOrderingProvider: ['type', _BpmnOrderingProvider2.default] }; },{"./BpmnOrderingProvider":190,"diagram-js/lib/i18n/translate":376}],192:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = PaletteProvider; var _minDash = require('min-dash'); /** * A palette provider for BPMN 2.0 elements. */ function PaletteProvider(palette, create, elementFactory, spaceTool, lassoTool, handTool, globalConnect, translate) { this._palette = palette; this._create = create; this._elementFactory = elementFactory; this._spaceTool = spaceTool; this._lassoTool = lassoTool; this._handTool = handTool; this._globalConnect = globalConnect; this._translate = translate; palette.registerProvider(this); } PaletteProvider.$inject = ['palette', 'create', 'elementFactory', 'spaceTool', 'lassoTool', 'handTool', 'globalConnect', 'translate']; PaletteProvider.prototype.getPaletteEntries = function (element) { var actions = {}, create = this._create, elementFactory = this._elementFactory, spaceTool = this._spaceTool, lassoTool = this._lassoTool, handTool = this._handTool, globalConnect = this._globalConnect, translate = this._translate; function createAction(type, group, className, title, options) { function createListener(event) { var shape = elementFactory.createShape((0, _minDash.assign)({ type: type }, options)); if (options) { shape.businessObject.di.isExpanded = options.isExpanded; } create.start(event, shape); } var shortType = type.replace(/^bpmn:/, ''); return { group: group, className: className, title: title || translate('Create {type}', { type: shortType }), action: { dragstart: createListener, click: createListener } }; } function createParticipant(event, collapsed) { create.start(event, elementFactory.createParticipantShape(collapsed)); } (0, _minDash.assign)(actions, { 'hand-tool': { group: 'tools', className: 'bpmn-icon-hand-tool', title: translate('Activate the hand tool'), action: { click: function click(event) { handTool.activateHand(event); } } }, 'lasso-tool': { group: 'tools', className: 'bpmn-icon-lasso-tool', title: translate('Activate the lasso tool'), action: { click: function click(event) { lassoTool.activateSelection(event); } } }, 'space-tool': { group: 'tools', className: 'bpmn-icon-space-tool', title: translate('Activate the create/remove space tool'), action: { click: function click(event) { spaceTool.activateSelection(event); } } }, 'global-connect-tool': { group: 'tools', className: 'bpmn-icon-connection-multi', title: translate('Activate the global connect tool'), action: { click: function click(event) { globalConnect.toggle(event); } } }, 'tool-separator': { group: 'tools', separator: true }, 'create.start-event': createAction('bpmn:StartEvent', 'event', 'bpmn-icon-start-event-none'), 'create.intermediate-event': createAction('bpmn:IntermediateThrowEvent', 'event', 'bpmn-icon-intermediate-event-none', translate('Create Intermediate/Boundary Event')), 'create.end-event': createAction('bpmn:EndEvent', 'event', 'bpmn-icon-end-event-none'), 'create.exclusive-gateway': createAction('bpmn:ExclusiveGateway', 'gateway', 'bpmn-icon-gateway-none', translate('Create Gateway')), 'create.task': createAction('bpmn:Task', 'activity', 'bpmn-icon-task'), 'create.data-object': createAction('bpmn:DataObjectReference', 'data-object', 'bpmn-icon-data-object'), 'create.data-store': createAction('bpmn:DataStoreReference', 'data-store', 'bpmn-icon-data-store'), 'create.subprocess-expanded': createAction('bpmn:SubProcess', 'activity', 'bpmn-icon-subprocess-expanded', translate('Create expanded SubProcess'), { isExpanded: true }), 'create.participant-expanded': { group: 'collaboration', className: 'bpmn-icon-participant', title: translate('Create Pool/Participant'), action: { dragstart: createParticipant, click: createParticipant } } }); return actions; }; },{"min-dash":505}],193:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _palette = require('diagram-js/lib/features/palette'); var _palette2 = _interopRequireDefault(_palette); var _create = require('diagram-js/lib/features/create'); var _create2 = _interopRequireDefault(_create); var _spaceTool = require('diagram-js/lib/features/space-tool'); var _spaceTool2 = _interopRequireDefault(_spaceTool); var _lassoTool = require('diagram-js/lib/features/lasso-tool'); var _lassoTool2 = _interopRequireDefault(_lassoTool); var _handTool = require('diagram-js/lib/features/hand-tool'); var _handTool2 = _interopRequireDefault(_handTool); var _globalConnect = require('diagram-js/lib/features/global-connect'); var _globalConnect2 = _interopRequireDefault(_globalConnect); var _translate = require('diagram-js/lib/i18n/translate'); var _translate2 = _interopRequireDefault(_translate); var _PaletteProvider = require('./PaletteProvider'); var _PaletteProvider2 = _interopRequireDefault(_PaletteProvider); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_palette2.default, _create2.default, _spaceTool2.default, _lassoTool2.default, _handTool2.default, _globalConnect2.default, _translate2.default], __init__: ['paletteProvider'], paletteProvider: ['type', _PaletteProvider2.default] }; },{"./PaletteProvider":192,"diagram-js/lib/features/create":281,"diagram-js/lib/features/global-connect":290,"diagram-js/lib/features/hand-tool":292,"diagram-js/lib/features/lasso-tool":304,"diagram-js/lib/features/palette":341,"diagram-js/lib/features/space-tool":368,"diagram-js/lib/i18n/translate":376}],194:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ReplaceMenuProvider; var _ModelUtil = require('../../util/ModelUtil'); var _DiUtil = require('../../util/DiUtil'); var _TypeUtil = require('./util/TypeUtil'); var _minDash = require('min-dash'); var _ReplaceOptions = require('../replace/ReplaceOptions'); var replaceOptions = _interopRequireWildcard(_ReplaceOptions); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } /** * This module is an element agnostic replace menu provider for the popup menu. */ function ReplaceMenuProvider(popupMenu, modeling, moddle, bpmnReplace, rules, translate) { this._popupMenu = popupMenu; this._modeling = modeling; this._moddle = moddle; this._bpmnReplace = bpmnReplace; this._rules = rules; this._translate = translate; this.register(); } ReplaceMenuProvider.$inject = ['popupMenu', 'modeling', 'moddle', 'bpmnReplace', 'rules', 'translate']; /** * Register replace menu provider in the popup menu */ ReplaceMenuProvider.prototype.register = function () { this._popupMenu.registerProvider('bpmn-replace', this); }; /** * Get all entries from replaceOptions for the given element and apply filters * on them. Get for example only elements, which are different from the current one. * * @param {djs.model.Base} element * * @return {Array} a list of menu entry items */ ReplaceMenuProvider.prototype.getEntries = function (element) { var businessObject = element.businessObject; var rules = this._rules; var entries; if (!rules.allowed('shape.replace', { element: element })) { return []; } var differentType = (0, _TypeUtil.isDifferentType)(element); // start events outside event sub processes if ((0, _ModelUtil.is)(businessObject, 'bpmn:StartEvent') && !(0, _DiUtil.isEventSubProcess)(businessObject.$parent)) { entries = (0, _minDash.filter)(replaceOptions.START_EVENT, differentType); return this._createEntries(element, entries); } // expanded/collapsed pools if ((0, _ModelUtil.is)(businessObject, 'bpmn:Participant')) { entries = (0, _minDash.filter)(replaceOptions.PARTICIPANT, function (entry) { return (0, _DiUtil.isExpanded)(businessObject) !== entry.target.isExpanded; }); return this._createEntries(element, entries); } // start events inside event sub processes if ((0, _ModelUtil.is)(businessObject, 'bpmn:StartEvent') && (0, _DiUtil.isEventSubProcess)(businessObject.$parent)) { entries = (0, _minDash.filter)(replaceOptions.EVENT_SUB_PROCESS_START_EVENT, function (entry) { var target = entry.target; var isInterrupting = target.isInterrupting !== false; var isInterruptingEqual = (0, _ModelUtil.getBusinessObject)(element).isInterrupting === isInterrupting; // filters elements which types and event definition are equal but have have different interrupting types return differentType(entry) || !differentType(entry) && !isInterruptingEqual; }); return this._createEntries(element, entries); } // end events if ((0, _ModelUtil.is)(businessObject, 'bpmn:EndEvent')) { entries = (0, _minDash.filter)(replaceOptions.END_EVENT, function (entry) { var target = entry.target; // hide cancel end events outside transactions if (target.eventDefinitionType == 'bpmn:CancelEventDefinition' && !(0, _ModelUtil.is)(businessObject.$parent, 'bpmn:Transaction')) { return false; } return differentType(entry); }); return this._createEntries(element, entries); } // boundary events if ((0, _ModelUtil.is)(businessObject, 'bpmn:BoundaryEvent')) { entries = (0, _minDash.filter)(replaceOptions.BOUNDARY_EVENT, function (entry) { var target = entry.target; if (target.eventDefinition == 'bpmn:CancelEventDefinition' && !(0, _ModelUtil.is)(businessObject.attachedToRef, 'bpmn:Transaction')) { return false; } var cancelActivity = target.cancelActivity !== false; var isCancelActivityEqual = businessObject.cancelActivity == cancelActivity; return differentType(entry) || !differentType(entry) && !isCancelActivityEqual; }); return this._createEntries(element, entries); } // intermediate events if ((0, _ModelUtil.is)(businessObject, 'bpmn:IntermediateCatchEvent') || (0, _ModelUtil.is)(businessObject, 'bpmn:IntermediateThrowEvent')) { entries = (0, _minDash.filter)(replaceOptions.INTERMEDIATE_EVENT, differentType); return this._createEntries(element, entries); } // gateways if ((0, _ModelUtil.is)(businessObject, 'bpmn:Gateway')) { entries = (0, _minDash.filter)(replaceOptions.GATEWAY, differentType); return this._createEntries(element, entries); } // transactions if ((0, _ModelUtil.is)(businessObject, 'bpmn:Transaction')) { entries = (0, _minDash.filter)(replaceOptions.TRANSACTION, differentType); return this._createEntries(element, entries); } // expanded event sub processes if ((0, _DiUtil.isEventSubProcess)(businessObject) && (0, _DiUtil.isExpanded)(businessObject)) { entries = (0, _minDash.filter)(replaceOptions.EVENT_SUB_PROCESS, differentType); return this._createEntries(element, entries); } // expanded sub processes if ((0, _ModelUtil.is)(businessObject, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(businessObject)) { entries = (0, _minDash.filter)(replaceOptions.SUBPROCESS_EXPANDED, differentType); return this._createEntries(element, entries); } // collapsed ad hoc sub processes if ((0, _ModelUtil.is)(businessObject, 'bpmn:AdHocSubProcess') && !(0, _DiUtil.isExpanded)(businessObject)) { entries = (0, _minDash.filter)(replaceOptions.TASK, function (entry) { var target = entry.target; var isTargetSubProcess = target.type === 'bpmn:SubProcess'; var isTargetExpanded = target.isExpanded === true; return (0, _TypeUtil.isDifferentType)(element, target) && (!isTargetSubProcess || isTargetExpanded); }); return this._createEntries(element, entries); } // sequence flows if ((0, _ModelUtil.is)(businessObject, 'bpmn:SequenceFlow')) { return this._createSequenceFlowEntries(element, replaceOptions.SEQUENCE_FLOW); } // flow nodes if ((0, _ModelUtil.is)(businessObject, 'bpmn:FlowNode')) { entries = (0, _minDash.filter)(replaceOptions.TASK, differentType); // collapsed SubProcess can not be replaced with itself if ((0, _ModelUtil.is)(businessObject, 'bpmn:SubProcess') && !(0, _DiUtil.isExpanded)(businessObject)) { entries = (0, _minDash.filter)(entries, function (entry) { return entry.label !== 'Sub Process (collapsed)'; }); } return this._createEntries(element, entries); } return []; }; /** * Get a list of header items for the given element. This includes buttons * for multi instance markers and for the ad hoc marker. * * @param {djs.model.Base} element * * @return {Array} a list of menu entry items */ ReplaceMenuProvider.prototype.getHeaderEntries = function (element) { var headerEntries = []; if ((0, _ModelUtil.is)(element, 'bpmn:Activity') && !(0, _DiUtil.isEventSubProcess)(element)) { headerEntries = headerEntries.concat(this._getLoopEntries(element)); } if ((0, _ModelUtil.is)(element, 'bpmn:SubProcess') && !(0, _ModelUtil.is)(element, 'bpmn:Transaction') && !(0, _DiUtil.isEventSubProcess)(element)) { headerEntries.push(this._getAdHocEntry(element)); } return headerEntries; }; /** * Creates an array of menu entry objects for a given element and filters the replaceOptions * according to a filter function. * * @param {djs.model.Base} element * @param {Object} replaceOptions * * @return {Array} a list of menu items */ ReplaceMenuProvider.prototype._createEntries = function (element, replaceOptions) { var menuEntries = []; var self = this; (0, _minDash.forEach)(replaceOptions, function (definition) { var entry = self._createMenuEntry(definition, element); menuEntries.push(entry); }); return menuEntries; }; /** * Creates an array of menu entry objects for a given sequence flow. * * @param {djs.model.Base} element * @param {Object} replaceOptions * @return {Array} a list of menu items */ ReplaceMenuProvider.prototype._createSequenceFlowEntries = function (element, replaceOptions) { var businessObject = (0, _ModelUtil.getBusinessObject)(element); var menuEntries = []; var modeling = this._modeling, moddle = this._moddle; var self = this; (0, _minDash.forEach)(replaceOptions, function (entry) { switch (entry.actionName) { case 'replace-with-default-flow': if (businessObject.sourceRef.default !== businessObject && ((0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:ExclusiveGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:InclusiveGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:ComplexGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:Activity'))) { menuEntries.push(self._createMenuEntry(entry, element, function () { modeling.updateProperties(element.source, { default: businessObject }); })); } break; case 'replace-with-conditional-flow': if (!businessObject.conditionExpression && (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:Activity')) { menuEntries.push(self._createMenuEntry(entry, element, function () { var conditionExpression = moddle.create('bpmn:FormalExpression', { body: '' }); modeling.updateProperties(element, { conditionExpression: conditionExpression }); })); } break; default: // default flows if ((0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:Activity') && businessObject.conditionExpression) { return menuEntries.push(self._createMenuEntry(entry, element, function () { modeling.updateProperties(element, { conditionExpression: undefined }); })); } // conditional flows if (((0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:ExclusiveGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:InclusiveGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:ComplexGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:Activity')) && businessObject.sourceRef.default === businessObject) { return menuEntries.push(self._createMenuEntry(entry, element, function () { modeling.updateProperties(element.source, { default: undefined }); })); } } }); return menuEntries; }; /** * Creates and returns a single menu entry item. * * @param {Object} definition a single replace options definition object * @param {djs.model.Base} element * @param {Function} [action] an action callback function which gets called when * the menu entry is being triggered. * * @return {Object} menu entry item */ ReplaceMenuProvider.prototype._createMenuEntry = function (definition, element, action) { var translate = this._translate; var replaceElement = this._bpmnReplace.replaceElement; var replaceAction = function replaceAction() { return replaceElement(element, definition.target); }; action = action || replaceAction; var menuEntry = { label: translate(definition.label), className: definition.className, id: definition.actionName, action: action }; return menuEntry; }; /** * Get a list of menu items containing buttons for multi instance markers * * @param {djs.model.Base} element * * @return {Array} a list of menu items */ ReplaceMenuProvider.prototype._getLoopEntries = function (element) { var self = this; var translate = this._translate; function toggleLoopEntry(event, entry) { var loopCharacteristics; if (entry.active) { loopCharacteristics = undefined; } else { loopCharacteristics = self._moddle.create(entry.options.loopCharacteristics); if (entry.options.isSequential) { loopCharacteristics.isSequential = entry.options.isSequential; } } self._modeling.updateProperties(element, { loopCharacteristics: loopCharacteristics }); } var businessObject = (0, _ModelUtil.getBusinessObject)(element), loopCharacteristics = businessObject.loopCharacteristics; var isSequential, isLoop, isParallel; if (loopCharacteristics) { isSequential = loopCharacteristics.isSequential; isLoop = loopCharacteristics.isSequential === undefined; isParallel = loopCharacteristics.isSequential !== undefined && !loopCharacteristics.isSequential; } var loopEntries = [{ id: 'toggle-parallel-mi', className: 'bpmn-icon-parallel-mi-marker', title: translate('Parallel Multi Instance'), active: isParallel, action: toggleLoopEntry, options: { loopCharacteristics: 'bpmn:MultiInstanceLoopCharacteristics', isSequential: false } }, { id: 'toggle-sequential-mi', className: 'bpmn-icon-sequential-mi-marker', title: translate('Sequential Multi Instance'), active: isSequential, action: toggleLoopEntry, options: { loopCharacteristics: 'bpmn:MultiInstanceLoopCharacteristics', isSequential: true } }, { id: 'toggle-loop', className: 'bpmn-icon-loop-marker', title: translate('Loop'), active: isLoop, action: toggleLoopEntry, options: { loopCharacteristics: 'bpmn:StandardLoopCharacteristics' } }]; return loopEntries; }; /** * Get the menu items containing a button for the ad hoc marker * * @param {djs.model.Base} element * * @return {Object} a menu item */ ReplaceMenuProvider.prototype._getAdHocEntry = function (element) { var translate = this._translate; var businessObject = (0, _ModelUtil.getBusinessObject)(element); var isAdHoc = (0, _ModelUtil.is)(businessObject, 'bpmn:AdHocSubProcess'); var replaceElement = this._bpmnReplace.replaceElement; var adHocEntry = { id: 'toggle-adhoc', className: 'bpmn-icon-ad-hoc-marker', title: translate('Ad-hoc'), active: isAdHoc, action: function action(event, entry) { if (isAdHoc) { return replaceElement(element, { type: 'bpmn:SubProcess' }); } else { return replaceElement(element, { type: 'bpmn:AdHocSubProcess' }); } } }; return adHocEntry; }; },{"../../util/DiUtil":214,"../../util/ModelUtil":216,"../replace/ReplaceOptions":200,"./util/TypeUtil":196,"min-dash":505}],195:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _popupMenu = require('diagram-js/lib/features/popup-menu'); var _popupMenu2 = _interopRequireDefault(_popupMenu); var _replace = require('../replace'); var _replace2 = _interopRequireDefault(_replace); var _ReplaceMenuProvider = require('./ReplaceMenuProvider'); var _ReplaceMenuProvider2 = _interopRequireDefault(_ReplaceMenuProvider); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_popupMenu2.default, _replace2.default], __init__: ['replaceMenuProvider'], replaceMenuProvider: ['type', _ReplaceMenuProvider2.default] }; },{"../replace":201,"./ReplaceMenuProvider":194,"diagram-js/lib/features/popup-menu":343}],196:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.isDifferentType = isDifferentType; var _ModelUtil = require('../../../util/ModelUtil'); var _DiUtil = require('../../../util/DiUtil'); /** * Returns true, if an element is from a different type * than a target definition. Takes into account the type, * event definition type and triggeredByEvent property. * * @param {djs.model.Base} element * * @return {Boolean} */ function isDifferentType(element) { return function (entry) { var target = entry.target; var businessObject = (0, _ModelUtil.getBusinessObject)(element), eventDefinition = businessObject.eventDefinitions && businessObject.eventDefinitions[0]; var isTypeEqual = businessObject.$type === target.type; var isEventDefinitionEqual = (eventDefinition && eventDefinition.$type) === target.eventDefinitionType; var isTriggeredByEventEqual = businessObject.triggeredByEvent === target.triggeredByEvent; var isExpandedEqual = target.isExpanded === undefined || target.isExpanded === (0, _DiUtil.isExpanded)(businessObject); return !isTypeEqual || !isEventDefinitionEqual || !isTriggeredByEventEqual || !isExpandedEqual; }; } },{"../../../util/DiUtil":214,"../../../util/ModelUtil":216}],197:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnReplacePreview; var _CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _css = require('css.escape'); var _css2 = _interopRequireDefault(_css); var _minDash = require('min-dash'); var _minDom = require('min-dom'); var _tinySvg = require('tiny-svg'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 250; function BpmnReplacePreview(eventBus, elementRegistry, elementFactory, canvas, previewSupport) { _CommandInterceptor2.default.call(this, eventBus); /** * Replace the visuals of all elements in the context which can be replaced * * @param {Object} context */ function replaceVisual(context) { var replacements = context.canExecute.replacements; (0, _minDash.forEach)(replacements, function (replacement) { var id = replacement.oldElementId; var newElement = { type: replacement.newElementType }; // if the visual of the element is already replaced if (context.visualReplacements[id]) { return; } var element = elementRegistry.get(id); (0, _minDash.assign)(newElement, { x: element.x, y: element.y }); // create a temporary shape var tempShape = elementFactory.createShape(newElement); canvas.addShape(tempShape, element.parent); // select the original SVG element related to the element and hide it var gfx = (0, _minDom.query)('[data-element-id="' + (0, _css2.default)(element.id) + '"]', context.dragGroup); if (gfx) { (0, _tinySvg.attr)(gfx, { display: 'none' }); } // clone the gfx of the temporary shape and add it to the drag group var dragger = previewSupport.addDragger(tempShape, context.dragGroup); context.visualReplacements[id] = dragger; canvas.removeShape(tempShape); }); } /** * Restore the original visuals of the previously replaced elements * * @param {Object} context */ function restoreVisual(context) { var visualReplacements = context.visualReplacements; (0, _minDash.forEach)(visualReplacements, function (dragger, id) { var originalGfx = (0, _minDom.query)('[data-element-id="' + (0, _css2.default)(id) + '"]', context.dragGroup); if (originalGfx) { (0, _tinySvg.attr)(originalGfx, { display: 'inline' }); } dragger.remove(); if (visualReplacements[id]) { delete visualReplacements[id]; } }); } eventBus.on('shape.move.move', LOW_PRIORITY, function (event) { var context = event.context, canExecute = context.canExecute; if (!context.visualReplacements) { context.visualReplacements = {}; } if (canExecute.replacements) { replaceVisual(context); } else { restoreVisual(context); } }); } BpmnReplacePreview.$inject = ['eventBus', 'elementRegistry', 'elementFactory', 'canvas', 'previewSupport']; (0, _inherits2.default)(BpmnReplacePreview, _CommandInterceptor2.default); },{"css.escape":237,"diagram-js/lib/command/CommandInterceptor":243,"inherits":415,"min-dash":505,"min-dom":506,"tiny-svg":535}],198:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _previewSupport = require('diagram-js/lib/features/preview-support'); var _previewSupport2 = _interopRequireDefault(_previewSupport); var _BpmnReplacePreview = require('./BpmnReplacePreview'); var _BpmnReplacePreview2 = _interopRequireDefault(_BpmnReplacePreview); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_previewSupport2.default], __init__: ['bpmnReplacePreview'], bpmnReplacePreview: ['type', _BpmnReplacePreview2.default] }; },{"./BpmnReplacePreview":197,"diagram-js/lib/features/preview-support":345}],199:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnReplace; var _minDash = require('min-dash'); var _ModelUtil = require('../../util/ModelUtil'); var _ModelingUtil = require('../modeling/util/ModelingUtil'); var _DiUtil = require('../../util/DiUtil'); var _ModelCloneUtils = require('../../util/model/ModelCloneUtils'); var _ModelCloneHelper = require('../../util/model/ModelCloneHelper'); var _ModelCloneHelper2 = _interopRequireDefault(_ModelCloneHelper); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var CUSTOM_PROPERTIES = ['cancelActivity', 'instantiate', 'eventGatewayType', 'triggeredByEvent', 'isInterrupting']; function toggeling(element, target) { var oldCollapsed = element && (0, _minDash.has)(element, 'collapsed') ? element.collapsed : !(0, _DiUtil.isExpanded)(element); var targetCollapsed; if (target && ((0, _minDash.has)(target, 'collapsed') || (0, _minDash.has)(target, 'isExpanded'))) { // property is explicitly set so use it targetCollapsed = (0, _minDash.has)(target, 'collapsed') ? target.collapsed : !target.isExpanded; } else { // keep old state targetCollapsed = oldCollapsed; } if (oldCollapsed !== targetCollapsed) { element.collapsed = oldCollapsed; return true; } return false; } /** * This module takes care of replacing BPMN elements */ function BpmnReplace(bpmnFactory, replace, selection, modeling, eventBus) { var helper = new _ModelCloneHelper2.default(eventBus, bpmnFactory); /** * Prepares a new business object for the replacement element * and triggers the replace operation. * * @param {djs.model.Base} element * @param {Object} target * @param {Object} [hints] * * @return {djs.model.Base} the newly created element */ function replaceElement(element, target, hints) { hints = hints || {}; var type = target.type, oldBusinessObject = element.businessObject; if (isSubProcess(oldBusinessObject)) { if (type === 'bpmn:SubProcess') { if (toggeling(element, target)) { // expanding or collapsing process modeling.toggleCollapse(element); return element; } } } var newBusinessObject = bpmnFactory.create(type); var newElement = { type: type, businessObject: newBusinessObject }; var elementProps = (0, _ModelCloneUtils.getProperties)(oldBusinessObject.$descriptor), newElementProps = (0, _ModelCloneUtils.getProperties)(newBusinessObject.$descriptor, true), copyProps = intersection(elementProps, newElementProps); // initialize special properties defined in target definition (0, _minDash.assign)(newBusinessObject, (0, _minDash.pick)(target, CUSTOM_PROPERTIES)); var properties = (0, _minDash.filter)(copyProps, function (property) { var propName = property.replace(/bpmn:/, ''); // copying event definitions, unless we replace if (propName === 'eventDefinitions') { return hasEventDefinition(element, target.eventDefinitionType); } // retain loop characteristics if the target element // is not an event sub process if (propName === 'loopCharacteristics') { return !(0, _DiUtil.isEventSubProcess)(newBusinessObject); } // so the applied properties from 'target' don't get lost if (property in newBusinessObject) { return false; } if (propName === 'processRef' && target.isExpanded === false) { return false; } if (propName === 'triggeredByEvent') { return false; } return _ModelCloneUtils.IGNORED_PROPERTIES.indexOf(propName) === -1; }); newBusinessObject = helper.clone(oldBusinessObject, newBusinessObject, properties); // initialize custom BPMN extensions if (target.eventDefinitionType) { // only initialize with new eventDefinition // if we did not set an event definition yet, // i.e. because we cloned it if (!hasEventDefinition(newBusinessObject, target.eventDefinitionType)) { newElement.eventDefinitionType = target.eventDefinitionType; } } if ((0, _ModelUtil.is)(oldBusinessObject, 'bpmn:Activity')) { if (isSubProcess(oldBusinessObject)) { // no toggeling, so keep old state newElement.isExpanded = (0, _DiUtil.isExpanded)(oldBusinessObject); } // else if property is explicitly set, use it else if (target && (0, _minDash.has)(target, 'isExpanded')) { newElement.isExpanded = target.isExpanded; } // TODO: need also to respect min/max Size // copy size, from an expanded subprocess to an expanded alternative subprocess // except bpmn:Task, because Task is always expanded if ((0, _DiUtil.isExpanded)(oldBusinessObject) && !(0, _ModelUtil.is)(oldBusinessObject, 'bpmn:Task') && newElement.isExpanded) { newElement.width = element.width; newElement.height = element.height; } } // remove children if not expanding sub process if (isSubProcess(oldBusinessObject) && !isSubProcess(newBusinessObject)) { hints.moveChildren = false; } // transform collapsed/expanded pools if ((0, _ModelUtil.is)(oldBusinessObject, 'bpmn:Participant')) { // create expanded pool if (target.isExpanded === true) { newBusinessObject.processRef = bpmnFactory.create('bpmn:Process'); } else { // remove children when transforming to collapsed pool hints.moveChildren = false; } // apply same size newElement.width = element.width; newElement.height = element.height; } newBusinessObject.name = oldBusinessObject.name; // retain default flow's reference between inclusive <-> exclusive gateways and activities if ((0, _ModelingUtil.isAny)(oldBusinessObject, ['bpmn:ExclusiveGateway', 'bpmn:InclusiveGateway', 'bpmn:Activity']) && (0, _ModelingUtil.isAny)(newBusinessObject, ['bpmn:ExclusiveGateway', 'bpmn:InclusiveGateway', 'bpmn:Activity'])) { newBusinessObject.default = oldBusinessObject.default; } if ('fill' in oldBusinessObject.di || 'stroke' in oldBusinessObject.di) { (0, _minDash.assign)(newElement, { colors: (0, _minDash.pick)(oldBusinessObject.di, ['fill', 'stroke']) }); } newElement = replace.replaceElement(element, newElement, hints); if (hints.select !== false) { selection.select(newElement); } return newElement; } this.replaceElement = replaceElement; } BpmnReplace.$inject = ['bpmnFactory', 'replace', 'selection', 'modeling', 'eventBus']; function isSubProcess(bo) { return (0, _ModelUtil.is)(bo, 'bpmn:SubProcess'); } function hasEventDefinition(element, type) { var bo = (0, _ModelUtil.getBusinessObject)(element); return type && bo.get('eventDefinitions').some(function (definition) { return (0, _ModelUtil.is)(definition, type); }); } /** * Compute intersection between two arrays. */ function intersection(a1, a2) { return a1.filter(function (el) { return a2.indexOf(el) !== -1; }); } },{"../../util/DiUtil":214,"../../util/ModelUtil":216,"../../util/model/ModelCloneHelper":218,"../../util/model/ModelCloneUtils":219,"../modeling/util/ModelingUtil":189,"min-dash":505}],200:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var START_EVENT = exports.START_EVENT = [{ label: 'Start Event', actionName: 'replace-with-none-start', className: 'bpmn-icon-start-event-none', target: { type: 'bpmn:StartEvent' } }, { label: 'Intermediate Throw Event', actionName: 'replace-with-none-intermediate-throwing', className: 'bpmn-icon-intermediate-event-none', target: { type: 'bpmn:IntermediateThrowEvent' } }, { label: 'End Event', actionName: 'replace-with-none-end', className: 'bpmn-icon-end-event-none', target: { type: 'bpmn:EndEvent' } }, { label: 'Message Start Event', actionName: 'replace-with-message-start', className: 'bpmn-icon-start-event-message', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:MessageEventDefinition' } }, { label: 'Timer Start Event', actionName: 'replace-with-timer-start', className: 'bpmn-icon-start-event-timer', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:TimerEventDefinition' } }, { label: 'Conditional Start Event', actionName: 'replace-with-conditional-start', className: 'bpmn-icon-start-event-condition', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:ConditionalEventDefinition' } }, { label: 'Signal Start Event', actionName: 'replace-with-signal-start', className: 'bpmn-icon-start-event-signal', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:SignalEventDefinition' } }]; var INTERMEDIATE_EVENT = exports.INTERMEDIATE_EVENT = [{ label: 'Start Event', actionName: 'replace-with-none-start', className: 'bpmn-icon-start-event-none', target: { type: 'bpmn:StartEvent' } }, { label: 'Intermediate Throw Event', actionName: 'replace-with-none-intermediate-throw', className: 'bpmn-icon-intermediate-event-none', target: { type: 'bpmn:IntermediateThrowEvent' } }, { label: 'End Event', actionName: 'replace-with-none-end', className: 'bpmn-icon-end-event-none', target: { type: 'bpmn:EndEvent' } }, { label: 'Message Intermediate Catch Event', actionName: 'replace-with-message-intermediate-catch', className: 'bpmn-icon-intermediate-event-catch-message', target: { type: 'bpmn:IntermediateCatchEvent', eventDefinitionType: 'bpmn:MessageEventDefinition' } }, { label: 'Message Intermediate Throw Event', actionName: 'replace-with-message-intermediate-throw', className: 'bpmn-icon-intermediate-event-throw-message', target: { type: 'bpmn:IntermediateThrowEvent', eventDefinitionType: 'bpmn:MessageEventDefinition' } }, { label: 'Timer Intermediate Catch Event', actionName: 'replace-with-timer-intermediate-catch', className: 'bpmn-icon-intermediate-event-catch-timer', target: { type: 'bpmn:IntermediateCatchEvent', eventDefinitionType: 'bpmn:TimerEventDefinition' } }, { label: 'Escalation Intermediate Throw Event', actionName: 'replace-with-escalation-intermediate-throw', className: 'bpmn-icon-intermediate-event-throw-escalation', target: { type: 'bpmn:IntermediateThrowEvent', eventDefinitionType: 'bpmn:EscalationEventDefinition' } }, { label: 'Conditional Intermediate Catch Event', actionName: 'replace-with-conditional-intermediate-catch', className: 'bpmn-icon-intermediate-event-catch-condition', target: { type: 'bpmn:IntermediateCatchEvent', eventDefinitionType: 'bpmn:ConditionalEventDefinition' } }, { label: 'Link Intermediate Catch Event', actionName: 'replace-with-link-intermediate-catch', className: 'bpmn-icon-intermediate-event-catch-link', target: { type: 'bpmn:IntermediateCatchEvent', eventDefinitionType: 'bpmn:LinkEventDefinition' } }, { label: 'Link Intermediate Throw Event', actionName: 'replace-with-link-intermediate-throw', className: 'bpmn-icon-intermediate-event-throw-link', target: { type: 'bpmn:IntermediateThrowEvent', eventDefinitionType: 'bpmn:LinkEventDefinition' } }, { label: 'Compensation Intermediate Throw Event', actionName: 'replace-with-compensation-intermediate-throw', className: 'bpmn-icon-intermediate-event-throw-compensation', target: { type: 'bpmn:IntermediateThrowEvent', eventDefinitionType: 'bpmn:CompensateEventDefinition' } }, { label: 'Signal Intermediate Catch Event', actionName: 'replace-with-signal-intermediate-catch', className: 'bpmn-icon-intermediate-event-catch-signal', target: { type: 'bpmn:IntermediateCatchEvent', eventDefinitionType: 'bpmn:SignalEventDefinition' } }, { label: 'Signal Intermediate Throw Event', actionName: 'replace-with-signal-intermediate-throw', className: 'bpmn-icon-intermediate-event-throw-signal', target: { type: 'bpmn:IntermediateThrowEvent', eventDefinitionType: 'bpmn:SignalEventDefinition' } }]; var END_EVENT = exports.END_EVENT = [{ label: 'Start Event', actionName: 'replace-with-none-start', className: 'bpmn-icon-start-event-none', target: { type: 'bpmn:StartEvent' } }, { label: 'Intermediate Throw Event', actionName: 'replace-with-none-intermediate-throw', className: 'bpmn-icon-intermediate-event-none', target: { type: 'bpmn:IntermediateThrowEvent' } }, { label: 'End Event', actionName: 'replace-with-none-end', className: 'bpmn-icon-end-event-none', target: { type: 'bpmn:EndEvent' } }, { label: 'Message End Event', actionName: 'replace-with-message-end', className: 'bpmn-icon-end-event-message', target: { type: 'bpmn:EndEvent', eventDefinitionType: 'bpmn:MessageEventDefinition' } }, { label: 'Escalation End Event', actionName: 'replace-with-escalation-end', className: 'bpmn-icon-end-event-escalation', target: { type: 'bpmn:EndEvent', eventDefinitionType: 'bpmn:EscalationEventDefinition' } }, { label: 'Error End Event', actionName: 'replace-with-error-end', className: 'bpmn-icon-end-event-error', target: { type: 'bpmn:EndEvent', eventDefinitionType: 'bpmn:ErrorEventDefinition' } }, { label: 'Cancel End Event', actionName: 'replace-with-cancel-end', className: 'bpmn-icon-end-event-cancel', target: { type: 'bpmn:EndEvent', eventDefinitionType: 'bpmn:CancelEventDefinition' } }, { label: 'Compensation End Event', actionName: 'replace-with-compensation-end', className: 'bpmn-icon-end-event-compensation', target: { type: 'bpmn:EndEvent', eventDefinitionType: 'bpmn:CompensateEventDefinition' } }, { label: 'Signal End Event', actionName: 'replace-with-signal-end', className: 'bpmn-icon-end-event-signal', target: { type: 'bpmn:EndEvent', eventDefinitionType: 'bpmn:SignalEventDefinition' } }, { label: 'Terminate End Event', actionName: 'replace-with-terminate-end', className: 'bpmn-icon-end-event-terminate', target: { type: 'bpmn:EndEvent', eventDefinitionType: 'bpmn:TerminateEventDefinition' } }]; var GATEWAY = exports.GATEWAY = [{ label: 'Exclusive Gateway', actionName: 'replace-with-exclusive-gateway', className: 'bpmn-icon-gateway-xor', target: { type: 'bpmn:ExclusiveGateway' } }, { label: 'Parallel Gateway', actionName: 'replace-with-parallel-gateway', className: 'bpmn-icon-gateway-parallel', target: { type: 'bpmn:ParallelGateway' } }, { label: 'Inclusive Gateway', actionName: 'replace-with-inclusive-gateway', className: 'bpmn-icon-gateway-or', target: { type: 'bpmn:InclusiveGateway' } }, { label: 'Complex Gateway', actionName: 'replace-with-complex-gateway', className: 'bpmn-icon-gateway-complex', target: { type: 'bpmn:ComplexGateway' } }, { label: 'Event based Gateway', actionName: 'replace-with-event-based-gateway', className: 'bpmn-icon-gateway-eventbased', target: { type: 'bpmn:EventBasedGateway', instantiate: false, eventGatewayType: 'Exclusive' } // Gateways deactivated until https://github.com/bpmn-io/bpmn-js/issues/194 // { // label: 'Event based instantiating Gateway', // actionName: 'replace-with-exclusive-event-based-gateway', // className: 'bpmn-icon-exclusive-event-based', // target: { // type: 'bpmn:EventBasedGateway' // }, // options: { // businessObject: { instantiate: true, eventGatewayType: 'Exclusive' } // } // }, // { // label: 'Parallel Event based instantiating Gateway', // actionName: 'replace-with-parallel-event-based-instantiate-gateway', // className: 'bpmn-icon-parallel-event-based-instantiate-gateway', // target: { // type: 'bpmn:EventBasedGateway' // }, // options: { // businessObject: { instantiate: true, eventGatewayType: 'Parallel' } // } // } }]; var SUBPROCESS_EXPANDED = exports.SUBPROCESS_EXPANDED = [{ label: 'Transaction', actionName: 'replace-with-transaction', className: 'bpmn-icon-transaction', target: { type: 'bpmn:Transaction', isExpanded: true } }, { label: 'Event Sub Process', actionName: 'replace-with-event-subprocess', className: 'bpmn-icon-event-subprocess-expanded', target: { type: 'bpmn:SubProcess', triggeredByEvent: true, isExpanded: true } }, { label: 'Sub Process (collapsed)', actionName: 'replace-with-collapsed-subprocess', className: 'bpmn-icon-subprocess-collapsed', target: { type: 'bpmn:SubProcess', isExpanded: false } }]; var TRANSACTION = exports.TRANSACTION = [{ label: 'Sub Process', actionName: 'replace-with-subprocess', className: 'bpmn-icon-subprocess-expanded', target: { type: 'bpmn:SubProcess', isExpanded: true } }, { label: 'Event Sub Process', actionName: 'replace-with-event-subprocess', className: 'bpmn-icon-event-subprocess-expanded', target: { type: 'bpmn:SubProcess', triggeredByEvent: true, isExpanded: true } }]; var EVENT_SUB_PROCESS = exports.EVENT_SUB_PROCESS = [{ label: 'Sub Process', actionName: 'replace-with-subprocess', className: 'bpmn-icon-subprocess-expanded', target: { type: 'bpmn:SubProcess', isExpanded: true } }, { label: 'Transaction', actionName: 'replace-with-transaction', className: 'bpmn-icon-transaction', target: { type: 'bpmn:Transaction', isExpanded: true } }]; var TASK = exports.TASK = [{ label: 'Task', actionName: 'replace-with-task', className: 'bpmn-icon-task', target: { type: 'bpmn:Task' } }, { label: 'Send Task', actionName: 'replace-with-send-task', className: 'bpmn-icon-send', target: { type: 'bpmn:SendTask' } }, { label: 'Receive Task', actionName: 'replace-with-receive-task', className: 'bpmn-icon-receive', target: { type: 'bpmn:ReceiveTask' } }, { label: 'User Task', actionName: 'replace-with-user-task', className: 'bpmn-icon-user', target: { type: 'bpmn:UserTask' } }, { label: 'Manual Task', actionName: 'replace-with-manual-task', className: 'bpmn-icon-manual', target: { type: 'bpmn:ManualTask' } }, { label: 'Business Rule Task', actionName: 'replace-with-rule-task', className: 'bpmn-icon-business-rule', target: { type: 'bpmn:BusinessRuleTask' } }, { label: 'Service Task', actionName: 'replace-with-service-task', className: 'bpmn-icon-service', target: { type: 'bpmn:ServiceTask' } }, { label: 'Script Task', actionName: 'replace-with-script-task', className: 'bpmn-icon-script', target: { type: 'bpmn:ScriptTask' } }, { label: 'Call Activity', actionName: 'replace-with-call-activity', className: 'bpmn-icon-call-activity', target: { type: 'bpmn:CallActivity' } }, { label: 'Sub Process (collapsed)', actionName: 'replace-with-collapsed-subprocess', className: 'bpmn-icon-subprocess-collapsed', target: { type: 'bpmn:SubProcess', isExpanded: false } }, { label: 'Sub Process (expanded)', actionName: 'replace-with-expanded-subprocess', className: 'bpmn-icon-subprocess-expanded', target: { type: 'bpmn:SubProcess', isExpanded: true } }]; var BOUNDARY_EVENT = exports.BOUNDARY_EVENT = [{ label: 'Message Boundary Event', actionName: 'replace-with-message-boundary', className: 'bpmn-icon-intermediate-event-catch-message', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:MessageEventDefinition' } }, { label: 'Timer Boundary Event', actionName: 'replace-with-timer-boundary', className: 'bpmn-icon-intermediate-event-catch-timer', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:TimerEventDefinition' } }, { label: 'Escalation Boundary Event', actionName: 'replace-with-escalation-boundary', className: 'bpmn-icon-intermediate-event-catch-escalation', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:EscalationEventDefinition' } }, { label: 'Conditional Boundary Event', actionName: 'replace-with-conditional-boundary', className: 'bpmn-icon-intermediate-event-catch-condition', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:ConditionalEventDefinition' } }, { label: 'Error Boundary Event', actionName: 'replace-with-error-boundary', className: 'bpmn-icon-intermediate-event-catch-error', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:ErrorEventDefinition' } }, { label: 'Cancel Boundary Event', actionName: 'replace-with-cancel-boundary', className: 'bpmn-icon-intermediate-event-catch-cancel', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:CancelEventDefinition' } }, { label: 'Signal Boundary Event', actionName: 'replace-with-signal-boundary', className: 'bpmn-icon-intermediate-event-catch-signal', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:SignalEventDefinition' } }, { label: 'Compensation Boundary Event', actionName: 'replace-with-compensation-boundary', className: 'bpmn-icon-intermediate-event-catch-compensation', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:CompensateEventDefinition' } }, { label: 'Message Boundary Event (non-interrupting)', actionName: 'replace-with-non-interrupting-message-boundary', className: 'bpmn-icon-intermediate-event-catch-non-interrupting-message', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:MessageEventDefinition', cancelActivity: false } }, { label: 'Timer Boundary Event (non-interrupting)', actionName: 'replace-with-non-interrupting-timer-boundary', className: 'bpmn-icon-intermediate-event-catch-non-interrupting-timer', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:TimerEventDefinition', cancelActivity: false } }, { label: 'Escalation Boundary Event (non-interrupting)', actionName: 'replace-with-non-interrupting-escalation-boundary', className: 'bpmn-icon-intermediate-event-catch-non-interrupting-escalation', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:EscalationEventDefinition', cancelActivity: false } }, { label: 'Conditional Boundary Event (non-interrupting)', actionName: 'replace-with-non-interrupting-conditional-boundary', className: 'bpmn-icon-intermediate-event-catch-non-interrupting-condition', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:ConditionalEventDefinition', cancelActivity: false } }, { label: 'Signal Boundary Event (non-interrupting)', actionName: 'replace-with-non-interrupting-signal-boundary', className: 'bpmn-icon-intermediate-event-catch-non-interrupting-signal', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:SignalEventDefinition', cancelActivity: false } }]; var EVENT_SUB_PROCESS_START_EVENT = exports.EVENT_SUB_PROCESS_START_EVENT = [{ label: 'Message Start Event', actionName: 'replace-with-message-start', className: 'bpmn-icon-start-event-message', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:MessageEventDefinition' } }, { label: 'Timer Start Event', actionName: 'replace-with-timer-start', className: 'bpmn-icon-start-event-timer', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:TimerEventDefinition' } }, { label: 'Conditional Start Event', actionName: 'replace-with-conditional-start', className: 'bpmn-icon-start-event-condition', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:ConditionalEventDefinition' } }, { label: 'Signal Start Event', actionName: 'replace-with-signal-start', className: 'bpmn-icon-start-event-signal', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:SignalEventDefinition' } }, { label: 'Error Start Event', actionName: 'replace-with-error-start', className: 'bpmn-icon-start-event-error', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:ErrorEventDefinition' } }, { label: 'Escalation Start Event', actionName: 'replace-with-escalation-start', className: 'bpmn-icon-start-event-escalation', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:EscalationEventDefinition' } }, { label: 'Compensation Start Event', actionName: 'replace-with-compensation-start', className: 'bpmn-icon-start-event-compensation', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:CompensateEventDefinition' } }, { label: 'Message Start Event (non-interrupting)', actionName: 'replace-with-non-interrupting-message-start', className: 'bpmn-icon-start-event-non-interrupting-message', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:MessageEventDefinition', isInterrupting: false } }, { label: 'Timer Start Event (non-interrupting)', actionName: 'replace-with-non-interrupting-timer-start', className: 'bpmn-icon-start-event-non-interrupting-timer', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:TimerEventDefinition', isInterrupting: false } }, { label: 'Conditional Start Event (non-interrupting)', actionName: 'replace-with-non-interrupting-conditional-start', className: 'bpmn-icon-start-event-non-interrupting-condition', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:ConditionalEventDefinition', isInterrupting: false } }, { label: 'Signal Start Event (non-interrupting)', actionName: 'replace-with-non-interrupting-signal-start', className: 'bpmn-icon-start-event-non-interrupting-signal', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:SignalEventDefinition', isInterrupting: false } }, { label: 'Escalation Start Event (non-interrupting)', actionName: 'replace-with-non-interrupting-escalation-start', className: 'bpmn-icon-start-event-non-interrupting-escalation', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:EscalationEventDefinition', isInterrupting: false } }]; var SEQUENCE_FLOW = exports.SEQUENCE_FLOW = [{ label: 'Sequence Flow', actionName: 'replace-with-sequence-flow', className: 'bpmn-icon-connection' }, { label: 'Default Flow', actionName: 'replace-with-default-flow', className: 'bpmn-icon-default-flow' }, { label: 'Conditional Flow', actionName: 'replace-with-conditional-flow', className: 'bpmn-icon-conditional-flow' }]; var PARTICIPANT = exports.PARTICIPANT = [{ label: 'Expanded Pool', actionName: 'replace-with-expanded-pool', className: 'bpmn-icon-participant', target: { type: 'bpmn:Participant', isExpanded: true } }, { label: 'Collapsed Pool', actionName: 'replace-with-collapsed-pool', // TODO(@janstuemmel): maybe design new icon className: 'bpmn-icon-lane', target: { type: 'bpmn:Participant', isExpanded: false } }]; },{}],201:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _selection = require('diagram-js/lib/features/selection'); var _selection2 = _interopRequireDefault(_selection); var _replace = require('diagram-js/lib/features/replace'); var _replace2 = _interopRequireDefault(_replace); var _BpmnReplace = require('./BpmnReplace'); var _BpmnReplace2 = _interopRequireDefault(_BpmnReplace); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_selection2.default, _replace2.default], bpmnReplace: ['type', _BpmnReplace2.default] }; },{"./BpmnReplace":199,"diagram-js/lib/features/replace":347,"diagram-js/lib/features/selection":361}],202:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnRules; var _minDash = require('min-dash'); var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _ModelUtil = require('../../util/ModelUtil'); var _ModelingUtil = require('../modeling/util/ModelingUtil'); var _LabelUtil = require('../../util/LabelUtil'); var _DiUtil = require('../../util/DiUtil'); var _RuleProvider = require('diagram-js/lib/features/rules/RuleProvider'); var _RuleProvider2 = _interopRequireDefault(_RuleProvider); var _BpmnSnappingUtil = require('../snapping/BpmnSnappingUtil'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN specific modeling rule */ function BpmnRules(eventBus) { _RuleProvider2.default.call(this, eventBus); } (0, _inherits2.default)(BpmnRules, _RuleProvider2.default); BpmnRules.$inject = ['eventBus']; BpmnRules.prototype.init = function () { this.addRule('connection.start', function (context) { var source = context.source; return canStartConnection(source); }); this.addRule('connection.create', function (context) { var source = context.source, target = context.target, hints = context.hints || {}, targetParent = hints.targetParent, targetAttach = hints.targetAttach; // don't allow incoming connections on // newly created boundary events // to boundary events if (targetAttach) { return false; } // temporarily set target parent for scoping // checks to work if (targetParent) { target.parent = targetParent; } try { return canConnect(source, target); } finally { // unset temporary target parent if (targetParent) { target.parent = null; } } }); this.addRule('connection.reconnectStart', function (context) { var connection = context.connection, source = context.hover || context.source, target = connection.target; return canConnect(source, target, connection); }); this.addRule('connection.reconnectEnd', function (context) { var connection = context.connection, source = connection.source, target = context.hover || context.target; return canConnect(source, target, connection); }); this.addRule('connection.updateWaypoints', function (context) { // OK! but visually ignore return null; }); this.addRule('shape.resize', function (context) { var shape = context.shape, newBounds = context.newBounds; return canResize(shape, newBounds); }); this.addRule('elements.move', function (context) { var target = context.target, shapes = context.shapes, position = context.position; return canAttach(shapes, target, null, position) || canReplace(shapes, target, position) || canMove(shapes, target, position) || canInsert(shapes, target, position); }); this.addRule('shape.create', function (context) { return canCreate(context.shape, context.target, context.source, context.position); }); this.addRule('shape.attach', function (context) { return canAttach(context.shape, context.target, null, context.position); }); this.addRule('element.copy', function (context) { var collection = context.collection, element = context.element; return canCopy(collection, element); }); this.addRule('element.paste', function (context) { var parent = context.parent, element = context.element, position = context.position, source = context.source, target = context.target; if (source || target) { return canConnect(source, target); } return canAttach([element], parent, null, position) || canCreate(element, parent, null, position); }); this.addRule('elements.paste', function (context) { var tree = context.tree, target = context.target; return canPaste(tree, target); }); }; BpmnRules.prototype.canConnectMessageFlow = canConnectMessageFlow; BpmnRules.prototype.canConnectSequenceFlow = canConnectSequenceFlow; BpmnRules.prototype.canConnectDataAssociation = canConnectDataAssociation; BpmnRules.prototype.canConnectAssociation = canConnectAssociation; BpmnRules.prototype.canMove = canMove; BpmnRules.prototype.canAttach = canAttach; BpmnRules.prototype.canReplace = canReplace; BpmnRules.prototype.canDrop = canDrop; BpmnRules.prototype.canInsert = canInsert; BpmnRules.prototype.canCreate = canCreate; BpmnRules.prototype.canConnect = canConnect; BpmnRules.prototype.canResize = canResize; BpmnRules.prototype.canCopy = canCopy; /** * Utility functions for rule checking */ /** * Checks if given element can be used for starting connection. * * @param {Element} source * @return {Boolean} */ function canStartConnection(element) { if (nonExistingOrLabel(element)) { return null; } return (0, _ModelingUtil.isAny)(element, ['bpmn:FlowNode', 'bpmn:InteractionNode', 'bpmn:DataObjectReference', 'bpmn:DataStoreReference']); } function nonExistingOrLabel(element) { return !element || (0, _LabelUtil.isLabel)(element); } function isSame(a, b) { return a === b; } function getOrganizationalParent(element) { do { if ((0, _ModelUtil.is)(element, 'bpmn:Process')) { return (0, _ModelUtil.getBusinessObject)(element); } if ((0, _ModelUtil.is)(element, 'bpmn:Participant')) { return (0, _ModelUtil.getBusinessObject)(element).processRef || (0, _ModelUtil.getBusinessObject)(element); } } while (element = element.parent); } function isTextAnnotation(element) { return (0, _ModelUtil.is)(element, 'bpmn:TextAnnotation'); } function isCompensationBoundary(element) { return (0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && hasEventDefinition(element, 'bpmn:CompensateEventDefinition'); } function isForCompensation(e) { return (0, _ModelUtil.getBusinessObject)(e).isForCompensation; } function isSameOrganization(a, b) { var parentA = getOrganizationalParent(a), parentB = getOrganizationalParent(b); return parentA === parentB; } function isMessageFlowSource(element) { return (0, _ModelUtil.is)(element, 'bpmn:InteractionNode') && (!(0, _ModelUtil.is)(element, 'bpmn:Event') || (0, _ModelUtil.is)(element, 'bpmn:ThrowEvent') && hasEventDefinitionOrNone(element, 'bpmn:MessageEventDefinition')); } function isMessageFlowTarget(element) { return (0, _ModelUtil.is)(element, 'bpmn:InteractionNode') && !isForCompensation(element) && (!(0, _ModelUtil.is)(element, 'bpmn:Event') || (0, _ModelUtil.is)(element, 'bpmn:CatchEvent') && hasEventDefinitionOrNone(element, 'bpmn:MessageEventDefinition')); } function getScopeParent(element) { var parent = element; while (parent = parent.parent) { if ((0, _ModelUtil.is)(parent, 'bpmn:FlowElementsContainer')) { return (0, _ModelUtil.getBusinessObject)(parent); } if ((0, _ModelUtil.is)(parent, 'bpmn:Participant')) { return (0, _ModelUtil.getBusinessObject)(parent).processRef; } } return null; } function isSameScope(a, b) { var scopeParentA = getScopeParent(a), scopeParentB = getScopeParent(b); return scopeParentA && scopeParentA === scopeParentB; } function hasEventDefinition(element, eventDefinition) { var bo = (0, _ModelUtil.getBusinessObject)(element); return !!(0, _minDash.find)(bo.eventDefinitions || [], function (definition) { return (0, _ModelUtil.is)(definition, eventDefinition); }); } function hasEventDefinitionOrNone(element, eventDefinition) { var bo = (0, _ModelUtil.getBusinessObject)(element); return (bo.eventDefinitions || []).every(function (definition) { return (0, _ModelUtil.is)(definition, eventDefinition); }); } function isSequenceFlowSource(element) { return (0, _ModelUtil.is)(element, 'bpmn:FlowNode') && !(0, _ModelUtil.is)(element, 'bpmn:EndEvent') && !(0, _DiUtil.isEventSubProcess)(element) && !((0, _ModelUtil.is)(element, 'bpmn:IntermediateThrowEvent') && hasEventDefinition(element, 'bpmn:LinkEventDefinition')) && !isCompensationBoundary(element) && !isForCompensation(element); } function isSequenceFlowTarget(element) { return (0, _ModelUtil.is)(element, 'bpmn:FlowNode') && !(0, _ModelUtil.is)(element, 'bpmn:StartEvent') && !(0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && !(0, _DiUtil.isEventSubProcess)(element) && !((0, _ModelUtil.is)(element, 'bpmn:IntermediateCatchEvent') && hasEventDefinition(element, 'bpmn:LinkEventDefinition')) && !isForCompensation(element); } function isEventBasedTarget(element) { return (0, _ModelUtil.is)(element, 'bpmn:ReceiveTask') || (0, _ModelUtil.is)(element, 'bpmn:IntermediateCatchEvent') && (hasEventDefinition(element, 'bpmn:MessageEventDefinition') || hasEventDefinition(element, 'bpmn:TimerEventDefinition') || hasEventDefinition(element, 'bpmn:ConditionalEventDefinition') || hasEventDefinition(element, 'bpmn:SignalEventDefinition')); } function isConnection(element) { return element.waypoints; } function getParents(element) { var parents = []; while (element) { element = element.parent; if (element) { parents.push(element); } } return parents; } function isParent(possibleParent, element) { var allParents = getParents(element); return allParents.indexOf(possibleParent) !== -1; } function canConnect(source, target, connection) { if (nonExistingOrLabel(source) || nonExistingOrLabel(target)) { return null; } if (!(0, _ModelUtil.is)(connection, 'bpmn:DataAssociation')) { if (canConnectMessageFlow(source, target)) { return { type: 'bpmn:MessageFlow' }; } if (canConnectSequenceFlow(source, target)) { return { type: 'bpmn:SequenceFlow' }; } } var connectDataAssociation = canConnectDataAssociation(source, target); if (connectDataAssociation) { return connectDataAssociation; } if (isCompensationBoundary(source) && isForCompensation(target)) { return { type: 'bpmn:Association', associationDirection: 'One' }; } if (canConnectAssociation(source, target)) { return { type: 'bpmn:Association' }; } return false; } /** * Can an element be dropped into the target element * * @return {Boolean} */ function canDrop(element, target, position) { // can move labels everywhere if ((0, _LabelUtil.isLabel)(element)) { return true; } // disallow to create elements on collapsed pools if ((0, _ModelUtil.is)(target, 'bpmn:Participant') && !(0, _DiUtil.isExpanded)(target)) { return false; } // allow to create new participants on // on existing collaboration and process diagrams if ((0, _ModelUtil.is)(element, 'bpmn:Participant')) { return (0, _ModelUtil.is)(target, 'bpmn:Process') || (0, _ModelUtil.is)(target, 'bpmn:Collaboration'); } // allow creating lanes on participants and other lanes only if ((0, _ModelUtil.is)(element, 'bpmn:Lane')) { return (0, _ModelUtil.is)(target, 'bpmn:Participant') || (0, _ModelUtil.is)(target, 'bpmn:Lane'); } if ((0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent')) { return false; } // drop flow elements onto flow element containers // and participants if ((0, _ModelUtil.is)(element, 'bpmn:FlowElement') && !(0, _ModelUtil.is)(element, 'bpmn:DataStoreReference')) { if ((0, _ModelUtil.is)(target, 'bpmn:FlowElementsContainer')) { return (0, _DiUtil.isExpanded)(target); } return (0, _ModelingUtil.isAny)(target, ['bpmn:Participant', 'bpmn:Lane']); } // account for the fact that data associations are always // rendered and moved to top (Process or Collaboration level) // // artifacts may be placed wherever, too if ((0, _ModelingUtil.isAny)(element, ['bpmn:Artifact', 'bpmn:DataAssociation', 'bpmn:DataStoreReference'])) { return (0, _ModelingUtil.isAny)(target, ['bpmn:Collaboration', 'bpmn:Lane', 'bpmn:Participant', 'bpmn:Process', 'bpmn:SubProcess']); } if ((0, _ModelUtil.is)(element, 'bpmn:MessageFlow')) { return (0, _ModelUtil.is)(target, 'bpmn:Collaboration') || element.source.parent == target || element.target.parent == target; } return false; } function canPaste(tree, target) { var topLevel = tree[0], participants; if ((0, _ModelUtil.is)(target, 'bpmn:Collaboration')) { return (0, _minDash.every)(topLevel, function (e) { return e.type === 'bpmn:Participant'; }); } if ((0, _ModelUtil.is)(target, 'bpmn:Process')) { participants = (0, _minDash.some)(topLevel, function (e) { return e.type === 'bpmn:Participant'; }); return !(participants && target.children.length > 0); } // disallow to create elements on collapsed pools if ((0, _ModelUtil.is)(target, 'bpmn:Participant') && !(0, _DiUtil.isExpanded)(target)) { return false; } if ((0, _ModelUtil.is)(target, 'bpmn:FlowElementsContainer')) { return (0, _DiUtil.isExpanded)(target); } return (0, _ModelingUtil.isAny)(target, ['bpmn:Collaboration', 'bpmn:Lane', 'bpmn:Participant', 'bpmn:Process', 'bpmn:SubProcess']); } function isBoundaryEvent(element) { return !(0, _LabelUtil.isLabel)(element) && (0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent'); } function isLane(element) { return (0, _ModelUtil.is)(element, 'bpmn:Lane'); } /** * We treat IntermediateThrowEvents as boundary events during create, * this must be reflected in the rules. */ function isBoundaryCandidate(element) { return isBoundaryEvent(element) || (0, _ModelUtil.is)(element, 'bpmn:IntermediateThrowEvent') && !element.parent; } function isReceiveTaskAfterEventBasedGateway(element) { return (0, _ModelUtil.is)(element, 'bpmn:ReceiveTask') && (0, _minDash.find)(element.incoming, function (incoming) { return (0, _ModelUtil.is)(incoming.source, 'bpmn:EventBasedGateway'); }); } function canAttach(elements, target, source, position) { if (!Array.isArray(elements)) { elements = [elements]; } // disallow appending as boundary event if (source) { return false; } // only (re-)attach one element at a time if (elements.length !== 1) { return false; } var element = elements[0]; // do not attach labels if ((0, _LabelUtil.isLabel)(element)) { return false; } // only handle boundary events if (!isBoundaryCandidate(element)) { return false; } // allow default move operation if (!target) { return true; } // disallow drop on event sub processes if ((0, _DiUtil.isEventSubProcess)(target)) { return false; } // only allow drop on non compensation activities if (!(0, _ModelUtil.is)(target, 'bpmn:Activity') || isForCompensation(target)) { return false; } // only attach to subprocess border if (position && !(0, _BpmnSnappingUtil.getBoundaryAttachment)(position, target)) { return false; } // do not attach on receive tasks after event based gateways if (isReceiveTaskAfterEventBasedGateway(target)) { return false; } return 'attach'; } /** * Defines how to replace elements for a given target. * * Returns an array containing all elements which will be replaced. * * @example * * [{ id: 'IntermediateEvent_2', * type: 'bpmn:StartEvent' * }, * { id: 'IntermediateEvent_5', * type: 'bpmn:EndEvent' * }] * * @param {Array} elements * @param {Object} target * * @return {Object} an object containing all elements which have to be replaced */ function canReplace(elements, target, position) { if (!target) { return false; } var canExecute = { replacements: [] }; (0, _minDash.forEach)(elements, function (element) { if (!(0, _DiUtil.isEventSubProcess)(target)) { if ((0, _ModelUtil.is)(element, 'bpmn:StartEvent') && element.type !== 'label' && canDrop(element, target)) { // replace a non-interrupting start event by a blank interrupting start event // when the target is not an event sub process if (!(0, _DiUtil.isInterrupting)(element)) { canExecute.replacements.push({ oldElementId: element.id, newElementType: 'bpmn:StartEvent' }); } // replace an error/escalation/compansate start event by a blank interrupting start event // when the target is not an event sub process if ((0, _DiUtil.hasErrorEventDefinition)(element) || (0, _DiUtil.hasEscalationEventDefinition)(element) || (0, _DiUtil.hasCompensateEventDefinition)(element)) { canExecute.replacements.push({ oldElementId: element.id, newElementType: 'bpmn:StartEvent' }); } } } if (!(0, _ModelUtil.is)(target, 'bpmn:Transaction')) { if (hasEventDefinition(element, 'bpmn:CancelEventDefinition') && element.type !== 'label') { if ((0, _ModelUtil.is)(element, 'bpmn:EndEvent') && canDrop(element, target)) { canExecute.replacements.push({ oldElementId: element.id, newElementType: 'bpmn:EndEvent' }); } if ((0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && canAttach(element, target, null, position)) { canExecute.replacements.push({ oldElementId: element.id, newElementType: 'bpmn:BoundaryEvent' }); } } } }); return canExecute.replacements.length ? canExecute : false; } function canMove(elements, target) { // do not move selection containing boundary events if ((0, _minDash.some)(elements, isBoundaryEvent)) { return false; } // do not move selection containing lanes if ((0, _minDash.some)(elements, isLane)) { return false; } // allow default move check to start move operation if (!target) { return true; } return elements.every(function (element) { return canDrop(element, target); }); } function canCreate(shape, target, source, position) { if (!target) { return false; } if ((0, _LabelUtil.isLabel)(target)) { return null; } if (isSame(source, target)) { return false; } // ensure we do not drop the element // into source if (source && isParent(source, target)) { return false; } return canDrop(shape, target, position) || canInsert(shape, target, position); } function canResize(shape, newBounds) { if ((0, _ModelUtil.is)(shape, 'bpmn:SubProcess')) { return (0, _DiUtil.isExpanded)(shape) && (!newBounds || newBounds.width >= 100 && newBounds.height >= 80); } if ((0, _ModelUtil.is)(shape, 'bpmn:Lane')) { return !newBounds || newBounds.width >= 130 && newBounds.height >= 60; } if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) { return !newBounds || newBounds.width >= 250 && newBounds.height >= 50; } if (isTextAnnotation(shape)) { return true; } return false; } /** * Check, whether one side of the relationship * is a text annotation. */ function isOneTextAnnotation(source, target) { var sourceTextAnnotation = isTextAnnotation(source), targetTextAnnotation = isTextAnnotation(target); return (sourceTextAnnotation || targetTextAnnotation) && sourceTextAnnotation !== targetTextAnnotation; } function canConnectAssociation(source, target) { // do not connect connections if (isConnection(source) || isConnection(target)) { return false; } // compensation boundary events are exception if (isCompensationBoundary(source) && isForCompensation(target)) { return true; } // don't connect parent <-> child if (isParent(target, source) || isParent(source, target)) { return false; } // allow connection of associations between and return isOneTextAnnotation(source, target); } function canConnectMessageFlow(source, target) { return isMessageFlowSource(source) && isMessageFlowTarget(target) && !isSameOrganization(source, target); } function canConnectSequenceFlow(source, target) { return isSequenceFlowSource(source) && isSequenceFlowTarget(target) && isSameScope(source, target) && !((0, _ModelUtil.is)(source, 'bpmn:EventBasedGateway') && !isEventBasedTarget(target)); } function canConnectDataAssociation(source, target) { if ((0, _ModelingUtil.isAny)(source, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference']) && (0, _ModelingUtil.isAny)(target, ['bpmn:Activity', 'bpmn:ThrowEvent'])) { return { type: 'bpmn:DataInputAssociation' }; } if ((0, _ModelingUtil.isAny)(target, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference']) && (0, _ModelingUtil.isAny)(source, ['bpmn:Activity', 'bpmn:CatchEvent'])) { return { type: 'bpmn:DataOutputAssociation' }; } return false; } function canInsert(shape, flow, position) { if (!flow) { return false; } if (Array.isArray(shape)) { if (shape.length !== 1) { return false; } shape = shape[0]; } if (flow.source === shape || flow.target === shape) { return false; } // return true if we can drop on the // underlying flow parent // // at this point we are not really able to talk // about connection rules (yet) return (0, _ModelingUtil.isAny)(flow, ['bpmn:SequenceFlow', 'bpmn:MessageFlow']) && !(0, _LabelUtil.isLabel)(flow) && (0, _ModelUtil.is)(shape, 'bpmn:FlowNode') && !(0, _ModelUtil.is)(shape, 'bpmn:BoundaryEvent') && canDrop(shape, flow.parent, position); } function contains(collection, element) { return collection && element && collection.indexOf(element) !== -1; } function canCopy(collection, element) { if ((0, _ModelUtil.is)(element, 'bpmn:Lane') && !contains(collection, element.parent)) { return false; } if ((0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && !contains(collection, element.host)) { return false; } return true; } },{"../../util/DiUtil":214,"../../util/LabelUtil":215,"../../util/ModelUtil":216,"../modeling/util/ModelingUtil":189,"../snapping/BpmnSnappingUtil":207,"diagram-js/lib/features/rules/RuleProvider":353,"inherits":415,"min-dash":505}],203:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _rules = require('diagram-js/lib/features/rules'); var _rules2 = _interopRequireDefault(_rules); var _BpmnRules = require('./BpmnRules'); var _BpmnRules2 = _interopRequireDefault(_BpmnRules); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_rules2.default], __init__: ['bpmnRules'], bpmnRules: ['type', _BpmnRules2.default] }; },{"./BpmnRules":202,"diagram-js/lib/features/rules":355}],204:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnSearchProvider; var _minDash = require('min-dash'); var _LabelUtil = require('../label-editing/LabelUtil'); /** * Provides ability to search through BPMN elements */ function BpmnSearchProvider(elementRegistry, searchPad, canvas) { this._elementRegistry = elementRegistry; this._canvas = canvas; searchPad.registerProvider(this); } BpmnSearchProvider.$inject = ['elementRegistry', 'searchPad', 'canvas']; /** * Finds all elements that match given pattern * * : * { * primaryTokens: >, * secondaryTokens: >, * element: * } * * : * { * normal|matched: * } * * @param {String} pattern * @return {Array} */ BpmnSearchProvider.prototype.find = function (pattern) { var rootElement = this._canvas.getRootElement(); var elements = this._elementRegistry.filter(function (element) { if (element.labelTarget) { return false; } return true; }); // do not include root element elements = (0, _minDash.filter)(elements, function (element) { return element !== rootElement; }); elements = (0, _minDash.map)(elements, function (element) { return { primaryTokens: matchAndSplit((0, _LabelUtil.getLabel)(element), pattern), secondaryTokens: matchAndSplit(element.id, pattern), element: element }; }); // exclude non-matched elements elements = (0, _minDash.filter)(elements, function (element) { return hasMatched(element.primaryTokens) || hasMatched(element.secondaryTokens); }); elements = (0, _minDash.sortBy)(elements, function (element) { return (0, _LabelUtil.getLabel)(element.element) + element.element.id; }); return elements; }; function hasMatched(tokens) { var matched = (0, _minDash.filter)(tokens, function (t) { return !!t.matched; }); return matched.length > 0; } function matchAndSplit(text, pattern) { var tokens = [], originalText = text; if (!text) { return tokens; } text = text.toLowerCase(); pattern = pattern.toLowerCase(); var i = text.indexOf(pattern); if (i > -1) { if (i !== 0) { tokens.push({ normal: originalText.substr(0, i) }); } tokens.push({ matched: originalText.substr(i, pattern.length) }); if (pattern.length + i < text.length) { tokens.push({ normal: originalText.substr(pattern.length + i, text.length) }); } } else { tokens.push({ normal: originalText }); } return tokens; } },{"../label-editing/LabelUtil":142,"min-dash":505}],205:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _searchPad = require('diagram-js/lib/features/search-pad'); var _searchPad2 = _interopRequireDefault(_searchPad); var _BpmnSearchProvider = require('./BpmnSearchProvider'); var _BpmnSearchProvider2 = _interopRequireDefault(_BpmnSearchProvider); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_searchPad2.default], __init__: ['bpmnSearch'], bpmnSearch: ['type', _BpmnSearchProvider2.default] }; },{"./BpmnSearchProvider":204,"diagram-js/lib/features/search-pad":357}],206:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnSnapping; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _minDash = require('min-dash'); var _Elements = require('diagram-js/lib/util/Elements'); var _ModelUtil = require('../../util/ModelUtil'); var _ModelingUtil = require('../modeling/util/ModelingUtil'); var _DiUtil = require('../../util/DiUtil'); var _Snapping = require('diagram-js/lib/features/snapping/Snapping'); var _Snapping2 = _interopRequireDefault(_Snapping); var _SnapUtil = require('diagram-js/lib/features/snapping/SnapUtil'); var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil'); var _BpmnSnappingUtil = require('./BpmnSnappingUtil'); var _LaneUtil = require('../modeling/util/LaneUtil'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var round = Math.round; var HIGH_PRIORITY = 1500; /** * BPMN specific snapping functionality * * * snap on process elements if a pool is created inside a * process diagram * * @param {EventBus} eventBus * @param {Canvas} canvas */ function BpmnSnapping(eventBus, canvas, bpmnRules, elementRegistry) { // instantiate super _Snapping2.default.call(this, eventBus, canvas); /** * Drop participant on process <> process elements snapping */ eventBus.on('create.start', function (event) { var context = event.context, shape = context.shape, rootElement = canvas.getRootElement(); // snap participant around existing elements (if any) if ((0, _ModelUtil.is)(shape, 'bpmn:Participant') && (0, _ModelUtil.is)(rootElement, 'bpmn:Process')) { initParticipantSnapping(context, shape, rootElement.children); } }); eventBus.on(['create.move', 'create.end'], HIGH_PRIORITY, function (event) { var context = event.context, shape = context.shape, participantSnapBox = context.participantSnapBox; if (!(0, _SnapUtil.isSnapped)(event) && participantSnapBox) { snapParticipant(participantSnapBox, shape, event); } }); eventBus.on('shape.move.start', function (event) { var context = event.context, shape = context.shape, rootElement = canvas.getRootElement(); // snap participant around existing elements (if any) if ((0, _ModelUtil.is)(shape, 'bpmn:Participant') && (0, _ModelUtil.is)(rootElement, 'bpmn:Process')) { initParticipantSnapping(context, shape, rootElement.children); } }); function canAttach(shape, target, position) { return bpmnRules.canAttach([shape], target, null, position) === 'attach'; } function canConnect(source, target) { return bpmnRules.canConnect(source, target); } /** * Snap boundary events to elements border */ eventBus.on(['create.move', 'create.end', 'shape.move.move', 'shape.move.end'], HIGH_PRIORITY, function (event) { var context = event.context, target = context.target, shape = context.shape; if (target && !(0, _SnapUtil.isSnapped)(event) && canAttach(shape, target, event)) { snapBoundaryEvent(event, shape, target); } }); /** * Adjust parent for flowElements to the target participant * when droping onto lanes. */ eventBus.on(['shape.move.hover', 'shape.move.move', 'shape.move.end', 'create.hover', 'create.move', 'create.end'], HIGH_PRIORITY, function (event) { var context = event.context, shape = context.shape, hover = event.hover; if ((0, _ModelUtil.is)(hover, 'bpmn:Lane') && !(0, _ModelingUtil.isAny)(shape, ['bpmn:Lane', 'bpmn:Participant'])) { event.hover = (0, _LaneUtil.getLanesRoot)(hover); event.hoverGfx = elementRegistry.getGraphics(event.hover); } }); /** * Snap sequence flows. */ eventBus.on(['connect.move', 'connect.hover', 'connect.end'], HIGH_PRIORITY, function (event) { var context = event.context, source = context.source, target = context.target; var connection = canConnect(source, target) || {}; if (!context.initialSourcePosition) { context.initialSourcePosition = context.sourcePosition; } if (target && (connection.type === 'bpmn:Association' || connection.type === 'bpmn:DataOutputAssociation' || connection.type === 'bpmn:DataInputAssociation' || connection.type === 'bpmn:SequenceFlow')) { // snap source context.sourcePosition = (0, _SnapUtil.mid)(source); // snap target snapToPosition(event, (0, _SnapUtil.mid)(target)); } else if (connection.type === 'bpmn:MessageFlow') { if ((0, _ModelUtil.is)(source, 'bpmn:Event')) { // snap source context.sourcePosition = (0, _SnapUtil.mid)(source); } if ((0, _ModelUtil.is)(target, 'bpmn:Event')) { // snap target snapToPosition(event, (0, _SnapUtil.mid)(target)); } } else { // otherwise reset source snap context.sourcePosition = context.initialSourcePosition; } }); eventBus.on('resize.start', HIGH_PRIORITY, function (event) { var context = event.context, shape = context.shape; if ((0, _ModelUtil.is)(shape, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(shape)) { context.minDimensions = { width: 140, height: 120 }; } if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) { context.minDimensions = { width: 300, height: 150 }; } if ((0, _ModelUtil.is)(shape, 'bpmn:Lane') || (0, _ModelUtil.is)(shape, 'bpmn:Participant')) { context.resizeConstraints = (0, _BpmnSnappingUtil.getParticipantSizeConstraints)(shape, context.direction, context.balanced); } if ((0, _ModelUtil.is)(shape, 'bpmn:TextAnnotation')) { context.minDimensions = { width: 50, height: 30 }; } }); } (0, _inherits2.default)(BpmnSnapping, _Snapping2.default); BpmnSnapping.$inject = ['eventBus', 'canvas', 'bpmnRules', 'elementRegistry']; BpmnSnapping.prototype.initSnap = function (event) { var context = event.context, shape = event.shape, shapeMid, shapeBounds, shapeTopLeft, shapeBottomRight, snapContext; snapContext = _Snapping2.default.prototype.initSnap.call(this, event); if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) { // assign higher priority for outer snaps on participants snapContext.setSnapLocations(['top-left', 'bottom-right', 'mid']); } if (shape) { shapeMid = (0, _SnapUtil.mid)(shape, event); shapeBounds = { width: shape.width, height: shape.height, x: isNaN(shape.x) ? round(shapeMid.x - shape.width / 2) : shape.x, y: isNaN(shape.y) ? round(shapeMid.y - shape.height / 2) : shape.y }; shapeTopLeft = (0, _SnapUtil.topLeft)(shapeBounds); shapeBottomRight = (0, _SnapUtil.bottomRight)(shapeBounds); snapContext.setSnapOrigin('top-left', { x: shapeTopLeft.x - event.x, y: shapeTopLeft.y - event.y }); snapContext.setSnapOrigin('bottom-right', { x: shapeBottomRight.x - event.x, y: shapeBottomRight.y - event.y }); (0, _minDash.forEach)(shape.outgoing, function (c) { var docking = c.waypoints[0]; docking = docking.original || docking; snapContext.setSnapOrigin(c.id + '-docking', { x: docking.x - event.x, y: docking.y - event.y }); }); (0, _minDash.forEach)(shape.incoming, function (c) { var docking = c.waypoints[c.waypoints.length - 1]; docking = docking.original || docking; snapContext.setSnapOrigin(c.id + '-docking', { x: docking.x - event.x, y: docking.y - event.y }); }); } var source = context.source; if (source) { snapContext.addDefaultSnap('mid', (0, _SnapUtil.mid)(source)); } }; BpmnSnapping.prototype.addTargetSnaps = function (snapPoints, shape, target) { // use target parent as snap target if ((0, _ModelUtil.is)(shape, 'bpmn:BoundaryEvent') && shape.type !== 'label') { target = target.parent; } // add sequence flow parents as snap targets if ((0, _ModelUtil.is)(target, 'bpmn:SequenceFlow')) { this.addTargetSnaps(snapPoints, shape, target.parent); } var siblings = this.getSiblings(shape, target) || []; (0, _minDash.forEach)(siblings, function (sibling) { // do not snap to lanes if ((0, _ModelUtil.is)(sibling, 'bpmn:Lane')) { return; } if (sibling.waypoints) { (0, _minDash.forEach)(sibling.waypoints.slice(1, -1), function (waypoint, i) { var nextWaypoint = sibling.waypoints[i + 2], previousWaypoint = sibling.waypoints[i]; if (!nextWaypoint || !previousWaypoint) { throw new Error('waypoints must exist'); } if (nextWaypoint.x === waypoint.x || nextWaypoint.y === waypoint.y || previousWaypoint.x === waypoint.x || previousWaypoint.y === waypoint.y) { snapPoints.add('mid', waypoint); } }); return; } snapPoints.add('mid', (0, _SnapUtil.mid)(sibling)); if ((0, _ModelUtil.is)(sibling, 'bpmn:Participant')) { snapPoints.add('top-left', (0, _SnapUtil.topLeft)(sibling)); snapPoints.add('bottom-right', (0, _SnapUtil.bottomRight)(sibling)); } }); (0, _minDash.forEach)(shape.incoming, function (c) { if (siblings.indexOf(c.source) === -1) { snapPoints.add('mid', (0, _SnapUtil.mid)(c.source)); } var docking = c.waypoints[0]; snapPoints.add(c.id + '-docking', docking.original || docking); }); (0, _minDash.forEach)(shape.outgoing, function (c) { if (siblings.indexOf(c.target) === -1) { snapPoints.add('mid', (0, _SnapUtil.mid)(c.target)); } var docking = c.waypoints[c.waypoints.length - 1]; snapPoints.add(c.id + '-docking', docking.original || docking); }); }; // participant snapping ////////////////////// function initParticipantSnapping(context, shape, elements) { if (!elements.length) { return; } var snapBox = (0, _Elements.getBBox)(elements.filter(function (e) { return !e.labelTarget && !e.waypoints; })); snapBox.x -= 50; snapBox.y -= 20; snapBox.width += 70; snapBox.height += 40; // adjust shape height to include bounding box shape.width = Math.max(shape.width, snapBox.width); shape.height = Math.max(shape.height, snapBox.height); context.participantSnapBox = snapBox; } function snapParticipant(snapBox, shape, event, offset) { offset = offset || 0; var shapeHalfWidth = shape.width / 2 - offset, shapeHalfHeight = shape.height / 2; var currentTopLeft = { x: event.x - shapeHalfWidth - offset, y: event.y - shapeHalfHeight }; var currentBottomRight = { x: event.x + shapeHalfWidth + offset, y: event.y + shapeHalfHeight }; var snapTopLeft = snapBox, snapBottomRight = (0, _SnapUtil.bottomRight)(snapBox); if (currentTopLeft.x >= snapTopLeft.x) { (0, _SnapUtil.setSnapped)(event, 'x', snapTopLeft.x + offset + shapeHalfWidth); } else if (currentBottomRight.x <= snapBottomRight.x) { (0, _SnapUtil.setSnapped)(event, 'x', snapBottomRight.x - offset - shapeHalfWidth); } if (currentTopLeft.y >= snapTopLeft.y) { (0, _SnapUtil.setSnapped)(event, 'y', snapTopLeft.y + shapeHalfHeight); } else if (currentBottomRight.y <= snapBottomRight.y) { (0, _SnapUtil.setSnapped)(event, 'y', snapBottomRight.y - shapeHalfHeight); } } // boundary event snapping ////////////////////// function snapBoundaryEvent(event, shape, target) { var targetTRBL = (0, _LayoutUtil.asTRBL)(target); var direction = (0, _BpmnSnappingUtil.getBoundaryAttachment)(event, target); if (/top/.test(direction)) { (0, _SnapUtil.setSnapped)(event, 'y', targetTRBL.top); } else if (/bottom/.test(direction)) { (0, _SnapUtil.setSnapped)(event, 'y', targetTRBL.bottom); } if (/left/.test(direction)) { (0, _SnapUtil.setSnapped)(event, 'x', targetTRBL.left); } else if (/right/.test(direction)) { (0, _SnapUtil.setSnapped)(event, 'x', targetTRBL.right); } } function snapToPosition(event, position) { (0, _SnapUtil.setSnapped)(event, 'x', position.x); (0, _SnapUtil.setSnapped)(event, 'y', position.y); } },{"../../util/DiUtil":214,"../../util/ModelUtil":216,"../modeling/util/LaneUtil":188,"../modeling/util/ModelingUtil":189,"./BpmnSnappingUtil":207,"diagram-js/lib/features/snapping/SnapUtil":363,"diagram-js/lib/features/snapping/Snapping":364,"diagram-js/lib/layout/LayoutUtil":380,"diagram-js/lib/util/Elements":396,"inherits":415,"min-dash":505}],207:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getBoundaryAttachment = getBoundaryAttachment; exports.getParticipantSizeConstraints = getParticipantSizeConstraints; var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil'); var _ModelUtil = require('../../util/ModelUtil'); var _LaneUtil = require('../modeling/util/LaneUtil'); function getBoundaryAttachment(position, targetBounds) { var orientation = (0, _LayoutUtil.getOrientation)(position, targetBounds, -15); if (orientation !== 'intersect') { return orientation; } else { return null; } } // participant snapping box implementation ////////////////////// var abs = Math.abs, min = Math.min, max = Math.max; function addToTrbl(trbl, attr, value, choice) { var current = trbl[attr]; // make sure to set the value if it does not exist // or apply the correct value by comparing against // choice(value, currentValue) trbl[attr] = current === undefined ? value : choice(value, current); } function addMin(trbl, attr, value) { return addToTrbl(trbl, attr, value, min); } function addMax(trbl, attr, value) { return addToTrbl(trbl, attr, value, max); } var LANE_MIN_HEIGHT = 60, LANE_MIN_WIDTH = 300, LANE_RIGHT_PADDING = 20, LANE_LEFT_PADDING = 50, LANE_TOP_PADDING = 20, LANE_BOTTOM_PADDING = 20; function getParticipantSizeConstraints(laneShape, resizeDirection, balanced) { var lanesRoot = (0, _LaneUtil.getLanesRoot)(laneShape); var isFirst = true, isLast = true; // max top/bottom size for lanes var allLanes = (0, _LaneUtil.collectLanes)(lanesRoot, [lanesRoot]); var laneTrbl = (0, _LayoutUtil.asTRBL)(laneShape); var maxTrbl = {}, minTrbl = {}; if (/e/.test(resizeDirection)) { minTrbl.right = laneTrbl.left + LANE_MIN_WIDTH; } else if (/w/.test(resizeDirection)) { minTrbl.left = laneTrbl.right - LANE_MIN_WIDTH; } allLanes.forEach(function (other) { var otherTrbl = (0, _LayoutUtil.asTRBL)(other); if (/n/.test(resizeDirection)) { if (otherTrbl.top < laneTrbl.top - 10) { isFirst = false; } // max top size (based on next element) if (balanced && abs(laneTrbl.top - otherTrbl.bottom) < 10) { addMax(maxTrbl, 'top', otherTrbl.top + LANE_MIN_HEIGHT); } // min top size (based on self or nested element) if (abs(laneTrbl.top - otherTrbl.top) < 5) { addMin(minTrbl, 'top', otherTrbl.bottom - LANE_MIN_HEIGHT); } } if (/s/.test(resizeDirection)) { if (otherTrbl.bottom > laneTrbl.bottom + 10) { isLast = false; } // max bottom size (based on previous element) if (balanced && abs(laneTrbl.bottom - otherTrbl.top) < 10) { addMin(maxTrbl, 'bottom', otherTrbl.bottom - LANE_MIN_HEIGHT); } // min bottom size (based on self or nested element) if (abs(laneTrbl.bottom - otherTrbl.bottom) < 5) { addMax(minTrbl, 'bottom', otherTrbl.top + LANE_MIN_HEIGHT); } } }); // max top/bottom/left/right size based on flow nodes var flowElements = lanesRoot.children.filter(function (s) { return !s.hidden && !s.waypoints && ((0, _ModelUtil.is)(s, 'bpmn:FlowElement') || (0, _ModelUtil.is)(s, 'bpmn:Artifact')); }); flowElements.forEach(function (flowElement) { var flowElementTrbl = (0, _LayoutUtil.asTRBL)(flowElement); if (isFirst && /n/.test(resizeDirection)) { addMin(minTrbl, 'top', flowElementTrbl.top - LANE_TOP_PADDING); } if (/e/.test(resizeDirection)) { addMax(minTrbl, 'right', flowElementTrbl.right + LANE_RIGHT_PADDING); } if (isLast && /s/.test(resizeDirection)) { addMax(minTrbl, 'bottom', flowElementTrbl.bottom + LANE_BOTTOM_PADDING); } if (/w/.test(resizeDirection)) { addMin(minTrbl, 'left', flowElementTrbl.left - LANE_LEFT_PADDING); } }); return { min: minTrbl, max: maxTrbl }; } },{"../../util/ModelUtil":216,"../modeling/util/LaneUtil":188,"diagram-js/lib/layout/LayoutUtil":380}],208:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _BpmnSnapping = require('./BpmnSnapping'); var _BpmnSnapping2 = _interopRequireDefault(_BpmnSnapping); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['snapping'], snapping: ['type', _BpmnSnapping2.default] }; },{"./BpmnSnapping":206}],209:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnImporter; var _minDash = require('min-dash'); var _ModelUtil = require('../util/ModelUtil'); var _LabelUtil = require('../util/LabelUtil'); var _LayoutUtil = require('diagram-js/lib/layout/LayoutUtil'); var _DiUtil = require('../util/DiUtil'); var _Util = require('./Util'); function elementData(semantic, attrs) { return (0, _minDash.assign)({ id: semantic.id, type: semantic.$type, businessObject: semantic }, attrs); } function collectWaypoints(waypoints) { return (0, _minDash.map)(waypoints, function (p) { return { x: p.x, y: p.y }; }); } function notYetDrawn(translate, semantic, refSemantic, property) { return new Error(translate('element {element} referenced by {referenced}#{property} not yet drawn', { element: (0, _Util.elementToString)(refSemantic), referenced: (0, _Util.elementToString)(semantic), property: property })); } /** * An importer that adds bpmn elements to the canvas * * @param {EventBus} eventBus * @param {Canvas} canvas * @param {ElementFactory} elementFactory * @param {ElementRegistry} elementRegistry * @param {Function} translate * @param {TextRenderer} textRenderer */ function BpmnImporter(eventBus, canvas, elementFactory, elementRegistry, translate, textRenderer) { this._eventBus = eventBus; this._canvas = canvas; this._elementFactory = elementFactory; this._elementRegistry = elementRegistry; this._translate = translate; this._textRenderer = textRenderer; } BpmnImporter.$inject = ['eventBus', 'canvas', 'elementFactory', 'elementRegistry', 'translate', 'textRenderer']; /** * Add bpmn element (semantic) to the canvas onto the * specified parent shape. */ BpmnImporter.prototype.add = function (semantic, parentElement) { var di = semantic.di, element, translate = this._translate, hidden; var parentIndex; // ROOT ELEMENT // handle the special case that we deal with a // invisible root element (process or collaboration) if ((0, _ModelUtil.is)(di, 'bpmndi:BPMNPlane')) { // add a virtual element (not being drawn) element = this._elementFactory.createRoot(elementData(semantic)); this._canvas.setRootElement(element); } // SHAPE else if ((0, _ModelUtil.is)(di, 'bpmndi:BPMNShape')) { var collapsed = !(0, _DiUtil.isExpanded)(semantic); hidden = parentElement && (parentElement.hidden || parentElement.collapsed); var bounds = semantic.di.bounds; element = this._elementFactory.createShape(elementData(semantic, { collapsed: collapsed, hidden: hidden, x: Math.round(bounds.x), y: Math.round(bounds.y), width: Math.round(bounds.width), height: Math.round(bounds.height) })); if ((0, _ModelUtil.is)(semantic, 'bpmn:BoundaryEvent')) { this._attachBoundary(semantic, element); } // insert lanes behind other flow nodes (cf. #727) if ((0, _ModelUtil.is)(semantic, 'bpmn:Lane')) { parentIndex = 0; } if ((0, _ModelUtil.is)(semantic, 'bpmn:DataStoreReference')) { // check wether data store is inside our outside of its semantic parent if (!isPointInsideBBox(parentElement, (0, _LayoutUtil.getMid)(bounds))) { parentElement = this._canvas.getRootElement(); } } this._canvas.addShape(element, parentElement, parentIndex); } // CONNECTION else if ((0, _ModelUtil.is)(di, 'bpmndi:BPMNEdge')) { var source = this._getSource(semantic), target = this._getTarget(semantic); hidden = parentElement && (parentElement.hidden || parentElement.collapsed); element = this._elementFactory.createConnection(elementData(semantic, { hidden: hidden, source: source, target: target, waypoints: collectWaypoints(semantic.di.waypoint) })); if ((0, _ModelUtil.is)(semantic, 'bpmn:DataAssociation')) { // render always on top; this ensures DataAssociations // are rendered correctly across different "hacks" people // love to model such as cross participant / sub process // associations parentElement = null; } // insert sequence flows behind other flow nodes (cf. #727) if ((0, _ModelUtil.is)(semantic, 'bpmn:SequenceFlow')) { parentIndex = 0; } this._canvas.addConnection(element, parentElement, parentIndex); } else { throw new Error(translate('unknown di {di} for element {semantic}', { di: (0, _Util.elementToString)(di), semantic: (0, _Util.elementToString)(semantic) })); } // (optional) LABEL if ((0, _LabelUtil.isLabelExternal)(semantic) && semantic.name) { this.addLabel(semantic, element); } this._eventBus.fire('bpmnElement.added', { element: element }); return element; }; /** * Attach the boundary element to the given host * * @param {ModdleElement} boundarySemantic * @param {djs.model.Base} boundaryElement */ BpmnImporter.prototype._attachBoundary = function (boundarySemantic, boundaryElement) { var translate = this._translate; var hostSemantic = boundarySemantic.attachedToRef; if (!hostSemantic) { throw new Error(translate('missing {semantic}#attachedToRef', { semantic: (0, _Util.elementToString)(boundarySemantic) })); } var host = this._elementRegistry.get(hostSemantic.id), attachers = host && host.attachers; if (!host) { throw notYetDrawn(translate, boundarySemantic, hostSemantic, 'attachedToRef'); } // wire element.host <> host.attachers boundaryElement.host = host; if (!attachers) { host.attachers = attachers = []; } if (attachers.indexOf(boundaryElement) === -1) { attachers.push(boundaryElement); } }; /** * add label for an element */ BpmnImporter.prototype.addLabel = function (semantic, element) { var bounds, text, label; bounds = (0, _LabelUtil.getExternalLabelBounds)(semantic, element); text = semantic.name; if (text) { // get corrected bounds from actual layouted text bounds = this._textRenderer.getExternalLabelBounds(bounds, text); } label = this._elementFactory.createLabel(elementData(semantic, { id: semantic.id + '_label', labelTarget: element, type: 'label', hidden: element.hidden || !semantic.name, x: Math.round(bounds.x), y: Math.round(bounds.y), width: Math.round(bounds.width), height: Math.round(bounds.height) })); return this._canvas.addShape(label, element.parent); }; /** * Return the drawn connection end based on the given side. * * @throws {Error} if the end is not yet drawn */ BpmnImporter.prototype._getEnd = function (semantic, side) { var element, refSemantic, type = semantic.$type, translate = this._translate; refSemantic = semantic[side + 'Ref']; // handle mysterious isMany DataAssociation#sourceRef if (side === 'source' && type === 'bpmn:DataInputAssociation') { refSemantic = refSemantic && refSemantic[0]; } // fix source / target for DataInputAssociation / DataOutputAssociation if (side === 'source' && type === 'bpmn:DataOutputAssociation' || side === 'target' && type === 'bpmn:DataInputAssociation') { refSemantic = semantic.$parent; } element = refSemantic && this._getElement(refSemantic); if (element) { return element; } if (refSemantic) { throw notYetDrawn(translate, semantic, refSemantic, side + 'Ref'); } else { throw new Error(translate('{semantic}#{side} Ref not specified', { semantic: (0, _Util.elementToString)(semantic), side: side })); } }; BpmnImporter.prototype._getSource = function (semantic) { return this._getEnd(semantic, 'source'); }; BpmnImporter.prototype._getTarget = function (semantic) { return this._getEnd(semantic, 'target'); }; BpmnImporter.prototype._getElement = function (semantic) { return this._elementRegistry.get(semantic.id); }; // helpers //////////////////// function isPointInsideBBox(bbox, point) { var x = point.x, y = point.y; return x >= bbox.x && x <= bbox.x + bbox.width && y >= bbox.y && y <= bbox.y + bbox.height; } },{"../util/DiUtil":214,"../util/LabelUtil":215,"../util/ModelUtil":216,"./Util":212,"diagram-js/lib/layout/LayoutUtil":380,"min-dash":505}],210:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnTreeWalker; var _minDash = require('min-dash'); var _objectRefs = require('object-refs'); var _objectRefs2 = _interopRequireDefault(_objectRefs); var _Util = require('./Util'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var diRefs = new _objectRefs2.default({ name: 'bpmnElement', enumerable: true }, { name: 'di', configurable: true }); /** * Returns true if an element has the given meta-model type * * @param {ModdleElement} element * @param {String} type * * @return {Boolean} */ function is(element, type) { return element.$instanceOf(type); } /** * Find a suitable display candidate for definitions where the DI does not * correctly specify one. */ function findDisplayCandidate(definitions) { return (0, _minDash.find)(definitions.rootElements, function (e) { return is(e, 'bpmn:Process') || is(e, 'bpmn:Collaboration'); }); } function BpmnTreeWalker(handler, translate) { // list of containers already walked var handledElements = {}; // list of elements to handle deferred to ensure // prerequisites are drawn var deferred = []; // Helpers ////////////////////// function contextual(fn, ctx) { return function (e) { fn(e, ctx); }; } function handled(element) { handledElements[element.id] = element; } function isHandled(element) { return handledElements[element.id]; } function visit(element, ctx) { var gfx = element.gfx; // avoid multiple rendering of elements if (gfx) { throw new Error(translate('already rendered {element}', { element: (0, _Util.elementToString)(element) })); } // call handler return handler.element(element, ctx); } function visitRoot(element, diagram) { return handler.root(element, diagram); } function visitIfDi(element, ctx) { try { var gfx = element.di && visit(element, ctx); handled(element); return gfx; } catch (e) { logError(e.message, { element: element, error: e }); console.error(translate('failed to import {element}', { element: (0, _Util.elementToString)(element) })); console.error(e); } } function logError(message, context) { handler.error(message, context); } // DI handling ////////////////////// function registerDi(di) { var bpmnElement = di.bpmnElement; if (bpmnElement) { if (bpmnElement.di) { logError(translate('multiple DI elements defined for {element}', { element: (0, _Util.elementToString)(bpmnElement) }), { element: bpmnElement }); } else { diRefs.bind(bpmnElement, 'di'); bpmnElement.di = di; } } else { logError(translate('no bpmnElement referenced in {element}', { element: (0, _Util.elementToString)(di) }), { element: di }); } } function handleDiagram(diagram) { handlePlane(diagram.plane); } function handlePlane(plane) { registerDi(plane); (0, _minDash.forEach)(plane.planeElement, handlePlaneElement); } function handlePlaneElement(planeElement) { registerDi(planeElement); } // Semantic handling ////////////////////// /** * Handle definitions and return the rendered diagram (if any) * * @param {ModdleElement} definitions to walk and import * @param {ModdleElement} [diagram] specific diagram to import and display * * @throws {Error} if no diagram to display could be found */ function handleDefinitions(definitions, diagram) { // make sure we walk the correct bpmnElement var diagrams = definitions.diagrams; if (diagram && diagrams.indexOf(diagram) === -1) { throw new Error(translate('diagram not part of bpmn:Definitions')); } if (!diagram && diagrams && diagrams.length) { diagram = diagrams[0]; } // no diagram -> nothing to import if (!diagram) { throw new Error(translate('no diagram to display')); } // load DI from selected diagram only handleDiagram(diagram); var plane = diagram.plane; if (!plane) { throw new Error(translate('no plane for {element}', { element: (0, _Util.elementToString)(diagram) })); } var rootElement = plane.bpmnElement; // ensure we default to a suitable display candidate (process or collaboration), // even if non is specified in DI if (!rootElement) { rootElement = findDisplayCandidate(definitions); if (!rootElement) { throw new Error(translate('no process or collaboration to display')); } else { logError(translate('correcting missing bpmnElement on {plane} to {rootElement}', { plane: (0, _Util.elementToString)(plane), rootElement: (0, _Util.elementToString)(rootElement) })); // correct DI on the fly plane.bpmnElement = rootElement; registerDi(plane); } } var ctx = visitRoot(rootElement, plane); if (is(rootElement, 'bpmn:Process')) { handleProcess(rootElement, ctx); } else if (is(rootElement, 'bpmn:Collaboration')) { handleCollaboration(rootElement, ctx); // force drawing of everything not yet drawn that is part of the target DI handleUnhandledProcesses(definitions.rootElements, ctx); } else { throw new Error(translate('unsupported bpmnElement for {plane}: {rootElement}', { plane: (0, _Util.elementToString)(plane), rootElement: (0, _Util.elementToString)(rootElement) })); } // handle all deferred elements handleDeferred(deferred); } function handleDeferred() { var fn; // drain deferred until empty while (deferred.length) { fn = deferred.shift(); fn(); } } function handleProcess(process, context) { handleFlowElementsContainer(process, context); handleIoSpecification(process.ioSpecification, context); handleArtifacts(process.artifacts, context); // log process handled handled(process); } function handleUnhandledProcesses(rootElements) { // walk through all processes that have not yet been drawn and draw them // if they contain lanes with DI information. // we do this to pass the free-floating lane test cases in the MIWG test suite var processes = (0, _minDash.filter)(rootElements, function (e) { return !isHandled(e) && is(e, 'bpmn:Process') && e.laneSets; }); processes.forEach(contextual(handleProcess)); } function handleMessageFlow(messageFlow, context) { visitIfDi(messageFlow, context); } function handleMessageFlows(messageFlows, context) { (0, _minDash.forEach)(messageFlows, contextual(handleMessageFlow, context)); } function handleDataAssociation(association, context) { visitIfDi(association, context); } function handleDataInput(dataInput, context) { visitIfDi(dataInput, context); } function handleDataOutput(dataOutput, context) { visitIfDi(dataOutput, context); } function handleArtifact(artifact, context) { // bpmn:TextAnnotation // bpmn:Group // bpmn:Association visitIfDi(artifact, context); } function handleArtifacts(artifacts, context) { (0, _minDash.forEach)(artifacts, function (e) { if (is(e, 'bpmn:Association')) { deferred.push(function () { handleArtifact(e, context); }); } else { handleArtifact(e, context); } }); } function handleIoSpecification(ioSpecification, context) { if (!ioSpecification) { return; } (0, _minDash.forEach)(ioSpecification.dataInputs, contextual(handleDataInput, context)); (0, _minDash.forEach)(ioSpecification.dataOutputs, contextual(handleDataOutput, context)); } function handleSubProcess(subProcess, context) { handleFlowElementsContainer(subProcess, context); handleArtifacts(subProcess.artifacts, context); } function handleFlowNode(flowNode, context) { var childCtx = visitIfDi(flowNode, context); if (is(flowNode, 'bpmn:SubProcess')) { handleSubProcess(flowNode, childCtx || context); } if (is(flowNode, 'bpmn:Activity')) { handleIoSpecification(flowNode.ioSpecification, context); } // defer handling of associations // affected types: // // * bpmn:Activity // * bpmn:ThrowEvent // * bpmn:CatchEvent // deferred.push(function () { (0, _minDash.forEach)(flowNode.dataInputAssociations, contextual(handleDataAssociation, context)); (0, _minDash.forEach)(flowNode.dataOutputAssociations, contextual(handleDataAssociation, context)); }); } function handleSequenceFlow(sequenceFlow, context) { visitIfDi(sequenceFlow, context); } function handleDataElement(dataObject, context) { visitIfDi(dataObject, context); } function handleBoundaryEvent(dataObject, context) { visitIfDi(dataObject, context); } function handleLane(lane, context) { deferred.push(function () { var newContext = visitIfDi(lane, context); if (lane.childLaneSet) { handleLaneSet(lane.childLaneSet, newContext || context); } wireFlowNodeRefs(lane); }); } function handleLaneSet(laneSet, context) { (0, _minDash.forEach)(laneSet.lanes, contextual(handleLane, context)); } function handleLaneSets(laneSets, context) { (0, _minDash.forEach)(laneSets, contextual(handleLaneSet, context)); } function handleFlowElementsContainer(container, context) { handleFlowElements(container.flowElements, context); if (container.laneSets) { handleLaneSets(container.laneSets, context); } } function handleFlowElements(flowElements, context) { (0, _minDash.forEach)(flowElements, function (e) { if (is(e, 'bpmn:SequenceFlow')) { deferred.push(function () { handleSequenceFlow(e, context); }); } else if (is(e, 'bpmn:BoundaryEvent')) { deferred.unshift(function () { handleBoundaryEvent(e, context); }); } else if (is(e, 'bpmn:FlowNode')) { handleFlowNode(e, context); } else if (is(e, 'bpmn:DataObject')) { // SKIP (assume correct referencing via DataObjectReference) } else if (is(e, 'bpmn:DataStoreReference')) { handleDataElement(e, context); } else if (is(e, 'bpmn:DataObjectReference')) { handleDataElement(e, context); } else { logError(translate('unrecognized flowElement {element} in context {context}', { element: (0, _Util.elementToString)(e), context: context ? (0, _Util.elementToString)(context.businessObject) : 'null' }), { element: e, context: context }); } }); } function handleParticipant(participant, context) { var newCtx = visitIfDi(participant, context); var process = participant.processRef; if (process) { handleProcess(process, newCtx || context); } } function handleCollaboration(collaboration) { (0, _minDash.forEach)(collaboration.participants, contextual(handleParticipant)); handleArtifacts(collaboration.artifacts); // handle message flows latest in the process deferred.push(function () { handleMessageFlows(collaboration.messageFlows); }); } function wireFlowNodeRefs(lane) { // wire the virtual flowNodeRefs <-> relationship (0, _minDash.forEach)(lane.flowNodeRef, function (flowNode) { var lanes = flowNode.get('lanes'); if (lanes) { lanes.push(lane); } }); } // API ////////////////////// return { handleDeferred: handleDeferred, handleDefinitions: handleDefinitions, handleSubProcess: handleSubProcess, registerDi: registerDi }; } },{"./Util":212,"min-dash":505,"object-refs":520}],211:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.importBpmnDiagram = importBpmnDiagram; var _BpmnTreeWalker = require('./BpmnTreeWalker'); var _BpmnTreeWalker2 = _interopRequireDefault(_BpmnTreeWalker); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Import the definitions into a diagram. * * Errors and warnings are reported through the specified callback. * * @param {Diagram} diagram * @param {ModdleElement} definitions * @param {Function} done the callback, invoked with (err, [ warning ]) once the import is done */ function importBpmnDiagram(diagram, definitions, done) { var importer, eventBus, translate; var error, warnings = []; /** * Walk the diagram semantically, importing (=drawing) * all elements you encounter. * * @param {ModdleElement} definitions */ function render(definitions) { var visitor = { root: function root(element) { return importer.add(element); }, element: function element(_element, parentShape) { return importer.add(_element, parentShape); }, error: function error(message, context) { warnings.push({ message: message, context: context }); } }; var walker = new _BpmnTreeWalker2.default(visitor, translate); // traverse BPMN 2.0 document model, // starting at definitions walker.handleDefinitions(definitions); } try { importer = diagram.get('bpmnImporter'); eventBus = diagram.get('eventBus'); translate = diagram.get('translate'); eventBus.fire('import.render.start', { definitions: definitions }); render(definitions); eventBus.fire('import.render.complete', { error: error, warnings: warnings }); } catch (e) { error = e; } done(error, warnings); } },{"./BpmnTreeWalker":210}],212:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.elementToString = elementToString; function elementToString(e) { if (!e) { return ''; } return '<' + e.$type + (e.id ? ' id="' + e.id : '') + '" />'; } },{}],213:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _translate = require('diagram-js/lib/i18n/translate'); var _translate2 = _interopRequireDefault(_translate); var _BpmnImporter = require('./BpmnImporter'); var _BpmnImporter2 = _interopRequireDefault(_BpmnImporter); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_translate2.default], bpmnImporter: ['type', _BpmnImporter2.default] }; },{"./BpmnImporter":209,"diagram-js/lib/i18n/translate":376}],214:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.isExpanded = isExpanded; exports.isInterrupting = isInterrupting; exports.isEventSubProcess = isEventSubProcess; exports.hasEventDefinition = hasEventDefinition; exports.hasErrorEventDefinition = hasErrorEventDefinition; exports.hasEscalationEventDefinition = hasEscalationEventDefinition; exports.hasCompensateEventDefinition = hasCompensateEventDefinition; var _ModelUtil = require('./ModelUtil'); var _minDash = require('min-dash'); function isExpanded(element) { if ((0, _ModelUtil.is)(element, 'bpmn:CallActivity')) { return false; } if ((0, _ModelUtil.is)(element, 'bpmn:SubProcess')) { return !!(0, _ModelUtil.getBusinessObject)(element).di.isExpanded; } if ((0, _ModelUtil.is)(element, 'bpmn:Participant')) { return !!(0, _ModelUtil.getBusinessObject)(element).processRef; } return true; } function isInterrupting(element) { return element && (0, _ModelUtil.getBusinessObject)(element).isInterrupting !== false; } function isEventSubProcess(element) { return element && !!(0, _ModelUtil.getBusinessObject)(element).triggeredByEvent; } function hasEventDefinition(element, eventType) { var bo = (0, _ModelUtil.getBusinessObject)(element), hasEventDefinition = false; if (bo.eventDefinitions) { (0, _minDash.forEach)(bo.eventDefinitions, function (event) { if ((0, _ModelUtil.is)(event, eventType)) { hasEventDefinition = true; } }); } return hasEventDefinition; } function hasErrorEventDefinition(element) { return hasEventDefinition(element, 'bpmn:ErrorEventDefinition'); } function hasEscalationEventDefinition(element) { return hasEventDefinition(element, 'bpmn:EscalationEventDefinition'); } function hasCompensateEventDefinition(element) { return hasEventDefinition(element, 'bpmn:CompensateEventDefinition'); } },{"./ModelUtil":216,"min-dash":505}],215:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.FLOW_LABEL_INDENT = exports.DEFAULT_LABEL_SIZE = undefined; exports.isLabelExternal = isLabelExternal; exports.hasExternalLabel = hasExternalLabel; exports.getFlowLabelPosition = getFlowLabelPosition; exports.getWaypointsMid = getWaypointsMid; exports.getExternalLabelMid = getExternalLabelMid; exports.getExternalLabelBounds = getExternalLabelBounds; exports.isLabel = isLabel; var _minDash = require('min-dash'); var _ModelUtil = require('./ModelUtil'); var DEFAULT_LABEL_SIZE = exports.DEFAULT_LABEL_SIZE = { width: 90, height: 20 }; var FLOW_LABEL_INDENT = exports.FLOW_LABEL_INDENT = 15; /** * Returns true if the given semantic has an external label * * @param {BpmnElement} semantic * @return {Boolean} true if has label */ function isLabelExternal(semantic) { return (0, _ModelUtil.is)(semantic, 'bpmn:Event') || (0, _ModelUtil.is)(semantic, 'bpmn:Gateway') || (0, _ModelUtil.is)(semantic, 'bpmn:DataStoreReference') || (0, _ModelUtil.is)(semantic, 'bpmn:DataObjectReference') || (0, _ModelUtil.is)(semantic, 'bpmn:SequenceFlow') || (0, _ModelUtil.is)(semantic, 'bpmn:MessageFlow'); } /** * Returns true if the given element has an external label * * @param {djs.model.shape} element * @return {Boolean} true if has label */ function hasExternalLabel(element) { return isLabel(element.label); } /** * Get the position for sequence flow labels * * @param {Array} waypoints * @return {Point} the label position */ function getFlowLabelPosition(waypoints) { // get the waypoints mid var mid = waypoints.length / 2 - 1; var first = waypoints[Math.floor(mid)]; var second = waypoints[Math.ceil(mid + 0.01)]; // get position var position = getWaypointsMid(waypoints); // calculate angle var angle = Math.atan((second.y - first.y) / (second.x - first.x)); var x = position.x, y = position.y; if (Math.abs(angle) < Math.PI / 2) { y -= FLOW_LABEL_INDENT; } else { x += FLOW_LABEL_INDENT; } return { x: x, y: y }; } /** * Get the middle of a number of waypoints * * @param {Array} waypoints * @return {Point} the mid point */ function getWaypointsMid(waypoints) { var mid = waypoints.length / 2 - 1; var first = waypoints[Math.floor(mid)]; var second = waypoints[Math.ceil(mid + 0.01)]; return { x: first.x + (second.x - first.x) / 2, y: first.y + (second.y - first.y) / 2 }; } function getExternalLabelMid(element) { if (element.waypoints) { return getFlowLabelPosition(element.waypoints); } else { return { x: element.x + element.width / 2, y: element.y + element.height + DEFAULT_LABEL_SIZE.height / 2 }; } } /** * Returns the bounds of an elements label, parsed from the elements DI or * generated from its bounds. * * @param {BpmnElement} semantic * @param {djs.model.Base} element */ function getExternalLabelBounds(semantic, element) { var mid, size, bounds, di = semantic.di, label = di.label; if (label && label.bounds) { bounds = label.bounds; size = { width: Math.max(DEFAULT_LABEL_SIZE.width, bounds.width), height: bounds.height }; mid = { x: bounds.x + bounds.width / 2, y: bounds.y + bounds.height / 2 }; } else { mid = getExternalLabelMid(element); size = DEFAULT_LABEL_SIZE; } return (0, _minDash.assign)({ x: mid.x - size.width / 2, y: mid.y - size.height / 2 }, size); } function isLabel(element) { return element && element.labelTarget; } },{"./ModelUtil":216,"min-dash":505}],216:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.is = is; exports.getBusinessObject = getBusinessObject; /** * Is an element of the given BPMN type? * * @param {djs.model.Base|ModdleElement} element * @param {String} type * * @return {Boolean} */ function is(element, type) { var bo = getBusinessObject(element); return bo && typeof bo.$instanceOf === 'function' && bo.$instanceOf(type); } /** * Return the business object for a given element. * * @param {djs.model.Base|ModdleElement} element * * @return {ModdleElement} */ function getBusinessObject(element) { return element && element.businessObject || element; } },{}],217:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.BPMNIO_IMG = undefined; exports.open = open; var _minDom = require('min-dom'); // inlined ../../resources/logo.svg var BPMNIO_LOGO_SVG = ''; /** * This file must not be changed or exchanged. * * @see http://bpmn.io/license for more information. */ var BPMNIO_LOGO_URL = 'data:image/svg+xml,' + encodeURIComponent(BPMNIO_LOGO_SVG); var BPMNIO_IMG = exports.BPMNIO_IMG = ''; function css(attrs) { return attrs.join(';'); } var LIGHTBOX_STYLES = css(['z-index: 1001', 'position: fixed', 'top: 0', 'left: 0', 'right: 0', 'bottom: 0']); var BACKDROP_STYLES = css(['width: 100%', 'height: 100%', 'background: rgba(0,0,0,0.2)']); var NOTICE_STYLES = css(['position: absolute', 'left: 50%', 'top: 40%', 'margin: 0 -130px', 'width: 260px', 'padding: 10px', 'background: white', 'border: solid 1px #AAA', 'border-radius: 3px', 'font-family: Helvetica, Arial, sans-serif', 'font-size: 14px', 'line-height: 1.2em']); var LIGHTBOX_MARKUP = '
' + '
' + '
' + '' + BPMNIO_IMG + '' + 'Web-based tooling for BPMN, DMN and CMMN diagrams ' + 'powered by bpmn.io.' + '
' + '
'; var lightbox; function open() { if (!lightbox) { lightbox = (0, _minDom.domify)(LIGHTBOX_MARKUP); _minDom.delegate.bind(lightbox, '.backdrop', 'click', function (event) { document.body.removeChild(lightbox); }); } document.body.appendChild(lightbox); } },{"min-dom":506}],218:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; exports.default = ModelCloneHelper; var _minDash = require('min-dash'); var _ModelCloneUtils = require('./ModelCloneUtils'); function isAllowedIn(extProp, type) { var allowedIn = extProp.meta.allowedIn; // '*' is a wildcard, which means any element is allowed to use this property if (allowedIn.length === 1 && allowedIn[0] === '*') { return true; } return allowedIn.indexOf(type) !== -1; } function isType(element, types) { return (0, _minDash.some)(types, function (type) { return (typeof element === 'undefined' ? 'undefined' : _typeof(element)) === type; }); } /** * A bpmn properties cloning interface * */ function ModelCloneHelper(eventBus, bpmnFactory) { this._eventBus = eventBus; this._bpmnFactory = bpmnFactory; } ModelCloneHelper.prototype.clone = function (refElement, newElement, properties) { var self = this; // hasNestedProperty: property allows us to avoid ending up with empty (xml) tags // f.ex: if extensionElements.values is empty, don't set it var context = { newElement: newElement, hasNestedProperty: false }; // we want the extensionElements to be cloned last // so that they can check certain properties properties = (0, _minDash.sortBy)(properties, function (prop) { return prop === 'bpmn:extensionElements'; }); (0, _minDash.forEach)(properties, function (propName) { var refElementProp = refElement.get(propName), newElementProp = newElement.get(propName), propDescriptor = newElement.$model.getPropertyDescriptor(newElement, propName), newProperty, name; // we're not interested in cloning: // - same values from simple types // - cloning id's // - cloning reference elements if (newElementProp === refElementProp) { return; } if (propDescriptor && (propDescriptor.isId || propDescriptor.isReference)) { return; } // if the property is of type 'boolean', 'string', 'number' or 'null', just set it if (isType(refElementProp, ['boolean', 'string', 'number']) || refElementProp === null) { newElement.set(propName, refElementProp); return; } if ((0, _minDash.isArray)(refElementProp)) { (0, _minDash.forEach)(refElementProp, function (extElement) { var newProp; context.refTopLevelProperty = extElement; newProp = self._deepClone(extElement, context); if (context.hasNestedProperty) { newProp.$parent = newElement; newElementProp.push(newProp); } context.hasNestedProperty = false; }); } else { name = propName.replace(/bpmn:/, ''); context.refTopLevelProperty = refElementProp; newProperty = self._deepClone(refElementProp, context); if (context.hasNestedProperty) { newProperty.$parent = newElement; newElement.set(name, newProperty); } context.hasNestedProperty = false; } }); return newElement; }; ModelCloneHelper.prototype._deepClone = function _deepClone(propertyElement, context) { var self = this; var eventBus = this._eventBus; var bpmnFactory = this._bpmnFactory; var newProp = bpmnFactory.create(propertyElement.$type); var properties = (0, _minDash.filter)(Object.keys(propertyElement), function (prop) { var descriptor = newProp.$model.getPropertyDescriptor(newProp, prop); if (descriptor && (descriptor.isId || descriptor.isReference)) { return false; } // we need to make sure we don't clone certain properties // which we cannot easily know if they hold references or not if (_ModelCloneUtils.IGNORED_PROPERTIES.indexOf(prop) !== -1) { return false; } // make sure we don't copy the type return prop !== '$type'; }); if (!properties.length) { context.hasNestedProperty = true; } (0, _minDash.forEach)(properties, function (propName) { // check if the propertyElement has this property defined if (propertyElement[propName] !== undefined && (propertyElement[propName].$type || (0, _minDash.isArray)(propertyElement[propName]))) { if ((0, _minDash.isArray)(propertyElement[propName])) { newProp[propName] = []; (0, _minDash.forEach)(propertyElement[propName], function (property) { var extProp = propertyElement.$model.getTypeDescriptor(property.$type), newDeepProp; // we're not going to copy undefined types if (!extProp) { return; } var canClone = eventBus.fire('property.clone', { newElement: context.newElement, refTopLevelProperty: context.refTopLevelProperty, propertyDescriptor: extProp }); if (!canClone) { // if can clone is 'undefined' or 'false' // check for the meta information if it is allowed if (propertyElement.$type === 'bpmn:ExtensionElements' && extProp.meta && extProp.meta.allowedIn && !isAllowedIn(extProp, context.newElement.$type)) { return false; } } newDeepProp = self._deepClone(property, context); newDeepProp.$parent = newProp; if (!newProp[propName]) { newProp[propName] = []; } context.hasNestedProperty = true; newProp[propName].push(newDeepProp); }); } else if (propertyElement[propName].$type) { newProp[propName] = self._deepClone(propertyElement[propName], context); if (newProp[propName]) { context.hasNestedProperty = true; newProp[propName].$parent = newProp; } } } else { context.hasNestedProperty = true; // just assign directly if it's a value newProp[propName] = propertyElement[propName]; } }); return newProp; }; },{"./ModelCloneUtils":219,"min-dash":505}],219:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.IGNORED_PROPERTIES = undefined; exports.getProperties = getProperties; var _minDash = require('min-dash'); /** * These are the properties that should be ignored when cloning elements. * * @type {Array} */ var IGNORED_PROPERTIES = exports.IGNORED_PROPERTIES = ['lanes', 'incoming', 'outgoing', 'artifacts', 'default', 'flowElements', 'dataInputAssociations', 'dataOutputAssociations']; function getProperties(descriptor, keepDefault) { var properties = []; (0, _minDash.forEach)(descriptor.properties, function (property) { if (keepDefault && property.default) { return; } properties.push(property.ns.name); }); return properties; } },{"min-dash":505}],220:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _simple = require('./lib/simple'); Object.defineProperty(exports, 'default', { enumerable: true, get: function get() { return _interopRequireDefault(_simple).default; } }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } },{"./lib/simple":222}],221:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnModdle; var _minDash = require('min-dash'); var _moddle = require('moddle'); var _moddle2 = _interopRequireDefault(_moddle); var _moddleXml = require('moddle-xml'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A sub class of {@link Moddle} with support for import and export of BPMN 2.0 xml files. * * @class BpmnModdle * @extends Moddle * * @param {Object|Array} packages to use for instantiating the model * @param {Object} [options] additional options to pass over */ function BpmnModdle(packages, options) { _moddle2.default.call(this, packages, options); } BpmnModdle.prototype = Object.create(_moddle2.default.prototype); /** * Instantiates a BPMN model tree from a given xml string. * * @param {String} xmlStr * @param {String} [typeName='bpmn:Definitions'] name of the root element * @param {Object} [options] options to pass to the underlying reader * @param {Function} done callback that is invoked with (err, result, parseContext) * once the import completes */ BpmnModdle.prototype.fromXML = function (xmlStr, typeName, options, done) { if (!(0, _minDash.isString)(typeName)) { done = options; options = typeName; typeName = 'bpmn:Definitions'; } if ((0, _minDash.isFunction)(options)) { done = options; options = {}; } var reader = new _moddleXml.Reader((0, _minDash.assign)({ model: this, lax: true }, options)); var rootHandler = reader.handler(typeName); reader.fromXML(xmlStr, rootHandler, done); }; /** * Serializes a BPMN 2.0 object tree to XML. * * @param {String} element the root element, typically an instance of `bpmn:Definitions` * @param {Object} [options] to pass to the underlying writer * @param {Function} done callback invoked with (err, xmlStr) once the import completes */ BpmnModdle.prototype.toXML = function (element, options, done) { if ((0, _minDash.isFunction)(options)) { done = options; options = {}; } var writer = new _moddleXml.Writer(options); var result; var err; try { result = writer.toXML(element); } catch (e) { err = e; } return done(err, result); }; },{"min-dash":505,"moddle":511,"moddle-xml":507}],222:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = function (additionalPackages, options) { var pks = (0, _minDash.assign)({}, packages, additionalPackages); return new _bpmnModdle2.default(pks, options); }; var _minDash = require('min-dash'); var _bpmnModdle = require('./bpmn-moddle'); var _bpmnModdle2 = _interopRequireDefault(_bpmnModdle); var _bpmn = require('../resources/bpmn/json/bpmn.json'); var _bpmn2 = _interopRequireDefault(_bpmn); var _bpmndi = require('../resources/bpmn/json/bpmndi.json'); var _bpmndi2 = _interopRequireDefault(_bpmndi); var _dc = require('../resources/bpmn/json/dc.json'); var _dc2 = _interopRequireDefault(_dc); var _di = require('../resources/bpmn/json/di.json'); var _di2 = _interopRequireDefault(_di); var _bioc = require('../resources/bpmn-io/json/bioc.json'); var _bioc2 = _interopRequireDefault(_bioc); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var packages = { bpmn: _bpmn2.default, bpmndi: _bpmndi2.default, dc: _dc2.default, di: _di2.default, bioc: _bioc2.default }; },{"../resources/bpmn-io/json/bioc.json":223,"../resources/bpmn/json/bpmn.json":224,"../resources/bpmn/json/bpmndi.json":225,"../resources/bpmn/json/dc.json":226,"../resources/bpmn/json/di.json":227,"./bpmn-moddle":221,"min-dash":505}],223:[function(require,module,exports){ module.exports={ "name": "bpmn.io colors for BPMN", "uri": "http://bpmn.io/schema/bpmn/biocolor/1.0", "prefix": "bioc", "types": [ { "name": "ColoredShape", "extends": [ "bpmndi:BPMNShape" ], "properties": [ { "name": "stroke", "isAttr": true, "type": "String" }, { "name": "fill", "isAttr": true, "type": "String" } ] }, { "name": "ColoredEdge", "extends": [ "bpmndi:BPMNEdge" ], "properties": [ { "name": "stroke", "isAttr": true, "type": "String" }, { "name": "fill", "isAttr": true, "type": "String" } ] } ], "enumerations": [], "associations": [] } },{}],224:[function(require,module,exports){ module.exports={ "name": "BPMN20", "uri": "http://www.omg.org/spec/BPMN/20100524/MODEL", "associations": [], "types": [ { "name": "Interface", "superClass": [ "RootElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "operations", "type": "Operation", "isMany": true }, { "name": "implementationRef", "type": "String", "isAttr": true } ] }, { "name": "Operation", "superClass": [ "BaseElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "inMessageRef", "type": "Message", "isReference": true }, { "name": "outMessageRef", "type": "Message", "isReference": true }, { "name": "errorRef", "type": "Error", "isMany": true, "isReference": true }, { "name": "implementationRef", "type": "String", "isAttr": true } ] }, { "name": "EndPoint", "superClass": [ "RootElement" ] }, { "name": "Auditing", "superClass": [ "BaseElement" ] }, { "name": "GlobalTask", "superClass": [ "CallableElement" ], "properties": [ { "name": "resources", "type": "ResourceRole", "isMany": true } ] }, { "name": "Monitoring", "superClass": [ "BaseElement" ] }, { "name": "Performer", "superClass": [ "ResourceRole" ] }, { "name": "Process", "superClass": [ "FlowElementsContainer", "CallableElement" ], "properties": [ { "name": "processType", "type": "ProcessType", "isAttr": true }, { "name": "isClosed", "isAttr": true, "type": "Boolean" }, { "name": "auditing", "type": "Auditing" }, { "name": "monitoring", "type": "Monitoring" }, { "name": "properties", "type": "Property", "isMany": true }, { "name": "laneSets", "type": "LaneSet", "isMany": true, "replaces": "FlowElementsContainer#laneSets" }, { "name": "flowElements", "type": "FlowElement", "isMany": true, "replaces": "FlowElementsContainer#flowElements" }, { "name": "artifacts", "type": "Artifact", "isMany": true }, { "name": "resources", "type": "ResourceRole", "isMany": true }, { "name": "correlationSubscriptions", "type": "CorrelationSubscription", "isMany": true }, { "name": "supports", "type": "Process", "isMany": true, "isReference": true }, { "name": "definitionalCollaborationRef", "type": "Collaboration", "isAttr": true, "isReference": true }, { "name": "isExecutable", "isAttr": true, "type": "Boolean" } ] }, { "name": "LaneSet", "superClass": [ "BaseElement" ], "properties": [ { "name": "lanes", "type": "Lane", "isMany": true }, { "name": "name", "isAttr": true, "type": "String" } ] }, { "name": "Lane", "superClass": [ "BaseElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "partitionElementRef", "type": "BaseElement", "isAttr": true, "isReference": true }, { "name": "partitionElement", "type": "BaseElement" }, { "name": "flowNodeRef", "type": "FlowNode", "isMany": true, "isReference": true }, { "name": "childLaneSet", "type": "LaneSet", "xml": { "serialize": "xsi:type" } } ] }, { "name": "GlobalManualTask", "superClass": [ "GlobalTask" ] }, { "name": "ManualTask", "superClass": [ "Task" ] }, { "name": "UserTask", "superClass": [ "Task" ], "properties": [ { "name": "renderings", "type": "Rendering", "isMany": true }, { "name": "implementation", "isAttr": true, "type": "String" } ] }, { "name": "Rendering", "superClass": [ "BaseElement" ] }, { "name": "HumanPerformer", "superClass": [ "Performer" ] }, { "name": "PotentialOwner", "superClass": [ "HumanPerformer" ] }, { "name": "GlobalUserTask", "superClass": [ "GlobalTask" ], "properties": [ { "name": "implementation", "isAttr": true, "type": "String" }, { "name": "renderings", "type": "Rendering", "isMany": true } ] }, { "name": "Gateway", "isAbstract": true, "superClass": [ "FlowNode" ], "properties": [ { "name": "gatewayDirection", "type": "GatewayDirection", "default": "Unspecified", "isAttr": true } ] }, { "name": "EventBasedGateway", "superClass": [ "Gateway" ], "properties": [ { "name": "instantiate", "default": false, "isAttr": true, "type": "Boolean" }, { "name": "eventGatewayType", "type": "EventBasedGatewayType", "isAttr": true, "default": "Exclusive" } ] }, { "name": "ComplexGateway", "superClass": [ "Gateway" ], "properties": [ { "name": "activationCondition", "type": "Expression", "xml": { "serialize": "xsi:type" } }, { "name": "default", "type": "SequenceFlow", "isAttr": true, "isReference": true } ] }, { "name": "ExclusiveGateway", "superClass": [ "Gateway" ], "properties": [ { "name": "default", "type": "SequenceFlow", "isAttr": true, "isReference": true } ] }, { "name": "InclusiveGateway", "superClass": [ "Gateway" ], "properties": [ { "name": "default", "type": "SequenceFlow", "isAttr": true, "isReference": true } ] }, { "name": "ParallelGateway", "superClass": [ "Gateway" ] }, { "name": "RootElement", "isAbstract": true, "superClass": [ "BaseElement" ] }, { "name": "Relationship", "superClass": [ "BaseElement" ], "properties": [ { "name": "type", "isAttr": true, "type": "String" }, { "name": "direction", "type": "RelationshipDirection", "isAttr": true }, { "name": "source", "isMany": true, "isReference": true, "type": "Element" }, { "name": "target", "isMany": true, "isReference": true, "type": "Element" } ] }, { "name": "BaseElement", "isAbstract": true, "properties": [ { "name": "id", "isAttr": true, "type": "String", "isId": true }, { "name": "documentation", "type": "Documentation", "isMany": true }, { "name": "extensionDefinitions", "type": "ExtensionDefinition", "isMany": true, "isReference": true }, { "name": "extensionElements", "type": "ExtensionElements" } ] }, { "name": "Extension", "properties": [ { "name": "mustUnderstand", "default": false, "isAttr": true, "type": "Boolean" }, { "name": "definition", "type": "ExtensionDefinition", "isAttr": true, "isReference": true } ] }, { "name": "ExtensionDefinition", "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "extensionAttributeDefinitions", "type": "ExtensionAttributeDefinition", "isMany": true } ] }, { "name": "ExtensionAttributeDefinition", "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "type", "isAttr": true, "type": "String" }, { "name": "isReference", "default": false, "isAttr": true, "type": "Boolean" }, { "name": "extensionDefinition", "type": "ExtensionDefinition", "isAttr": true, "isReference": true } ] }, { "name": "ExtensionElements", "properties": [ { "name": "valueRef", "isAttr": true, "isReference": true, "type": "Element" }, { "name": "values", "type": "Element", "isMany": true }, { "name": "extensionAttributeDefinition", "type": "ExtensionAttributeDefinition", "isAttr": true, "isReference": true } ] }, { "name": "Documentation", "superClass": [ "BaseElement" ], "properties": [ { "name": "text", "type": "String", "isBody": true }, { "name": "textFormat", "default": "text/plain", "isAttr": true, "type": "String" } ] }, { "name": "Event", "isAbstract": true, "superClass": [ "FlowNode", "InteractionNode" ], "properties": [ { "name": "properties", "type": "Property", "isMany": true } ] }, { "name": "IntermediateCatchEvent", "superClass": [ "CatchEvent" ] }, { "name": "IntermediateThrowEvent", "superClass": [ "ThrowEvent" ] }, { "name": "EndEvent", "superClass": [ "ThrowEvent" ] }, { "name": "StartEvent", "superClass": [ "CatchEvent" ], "properties": [ { "name": "isInterrupting", "default": true, "isAttr": true, "type": "Boolean" } ] }, { "name": "ThrowEvent", "isAbstract": true, "superClass": [ "Event" ], "properties": [ { "name": "dataInputs", "type": "DataInput", "isMany": true }, { "name": "dataInputAssociations", "type": "DataInputAssociation", "isMany": true }, { "name": "inputSet", "type": "InputSet" }, { "name": "eventDefinitions", "type": "EventDefinition", "isMany": true }, { "name": "eventDefinitionRef", "type": "EventDefinition", "isMany": true, "isReference": true } ] }, { "name": "CatchEvent", "isAbstract": true, "superClass": [ "Event" ], "properties": [ { "name": "parallelMultiple", "isAttr": true, "type": "Boolean", "default": false }, { "name": "dataOutputs", "type": "DataOutput", "isMany": true }, { "name": "dataOutputAssociations", "type": "DataOutputAssociation", "isMany": true }, { "name": "outputSet", "type": "OutputSet" }, { "name": "eventDefinitions", "type": "EventDefinition", "isMany": true }, { "name": "eventDefinitionRef", "type": "EventDefinition", "isMany": true, "isReference": true } ] }, { "name": "BoundaryEvent", "superClass": [ "CatchEvent" ], "properties": [ { "name": "cancelActivity", "default": true, "isAttr": true, "type": "Boolean" }, { "name": "attachedToRef", "type": "Activity", "isAttr": true, "isReference": true } ] }, { "name": "EventDefinition", "isAbstract": true, "superClass": [ "RootElement" ] }, { "name": "CancelEventDefinition", "superClass": [ "EventDefinition" ] }, { "name": "ErrorEventDefinition", "superClass": [ "EventDefinition" ], "properties": [ { "name": "errorRef", "type": "Error", "isAttr": true, "isReference": true } ] }, { "name": "TerminateEventDefinition", "superClass": [ "EventDefinition" ] }, { "name": "EscalationEventDefinition", "superClass": [ "EventDefinition" ], "properties": [ { "name": "escalationRef", "type": "Escalation", "isAttr": true, "isReference": true } ] }, { "name": "Escalation", "properties": [ { "name": "structureRef", "type": "ItemDefinition", "isAttr": true, "isReference": true }, { "name": "name", "isAttr": true, "type": "String" }, { "name": "escalationCode", "isAttr": true, "type": "String" } ], "superClass": [ "RootElement" ] }, { "name": "CompensateEventDefinition", "superClass": [ "EventDefinition" ], "properties": [ { "name": "waitForCompletion", "isAttr": true, "type": "Boolean", "default": true }, { "name": "activityRef", "type": "Activity", "isAttr": true, "isReference": true } ] }, { "name": "TimerEventDefinition", "superClass": [ "EventDefinition" ], "properties": [ { "name": "timeDate", "type": "Expression", "xml": { "serialize": "xsi:type" } }, { "name": "timeCycle", "type": "Expression", "xml": { "serialize": "xsi:type" } }, { "name": "timeDuration", "type": "Expression", "xml": { "serialize": "xsi:type" } } ] }, { "name": "LinkEventDefinition", "superClass": [ "EventDefinition" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "target", "type": "LinkEventDefinition", "isAttr": true, "isReference": true }, { "name": "source", "type": "LinkEventDefinition", "isMany": true, "isReference": true } ] }, { "name": "MessageEventDefinition", "superClass": [ "EventDefinition" ], "properties": [ { "name": "messageRef", "type": "Message", "isAttr": true, "isReference": true }, { "name": "operationRef", "type": "Operation", "isAttr": true, "isReference": true } ] }, { "name": "ConditionalEventDefinition", "superClass": [ "EventDefinition" ], "properties": [ { "name": "condition", "type": "Expression", "xml": { "serialize": "xsi:type" } } ] }, { "name": "SignalEventDefinition", "superClass": [ "EventDefinition" ], "properties": [ { "name": "signalRef", "type": "Signal", "isAttr": true, "isReference": true } ] }, { "name": "Signal", "superClass": [ "RootElement" ], "properties": [ { "name": "structureRef", "type": "ItemDefinition", "isAttr": true, "isReference": true }, { "name": "name", "isAttr": true, "type": "String" } ] }, { "name": "ImplicitThrowEvent", "superClass": [ "ThrowEvent" ] }, { "name": "DataState", "superClass": [ "BaseElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" } ] }, { "name": "ItemAwareElement", "superClass": [ "BaseElement" ], "properties": [ { "name": "itemSubjectRef", "type": "ItemDefinition", "isAttr": true, "isReference": true }, { "name": "dataState", "type": "DataState" } ] }, { "name": "DataAssociation", "superClass": [ "BaseElement" ], "properties": [ { "name": "assignment", "type": "Assignment", "isMany": true }, { "name": "sourceRef", "type": "ItemAwareElement", "isMany": true, "isReference": true }, { "name": "targetRef", "type": "ItemAwareElement", "isReference": true }, { "name": "transformation", "type": "FormalExpression", "xml": { "serialize": "property" } } ] }, { "name": "DataInput", "superClass": [ "ItemAwareElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "isCollection", "default": false, "isAttr": true, "type": "Boolean" }, { "name": "inputSetRef", "type": "InputSet", "isVirtual": true, "isMany": true, "isReference": true }, { "name": "inputSetWithOptional", "type": "InputSet", "isVirtual": true, "isMany": true, "isReference": true }, { "name": "inputSetWithWhileExecuting", "type": "InputSet", "isVirtual": true, "isMany": true, "isReference": true } ] }, { "name": "DataOutput", "superClass": [ "ItemAwareElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "isCollection", "default": false, "isAttr": true, "type": "Boolean" }, { "name": "outputSetRef", "type": "OutputSet", "isVirtual": true, "isMany": true, "isReference": true }, { "name": "outputSetWithOptional", "type": "OutputSet", "isVirtual": true, "isMany": true, "isReference": true }, { "name": "outputSetWithWhileExecuting", "type": "OutputSet", "isVirtual": true, "isMany": true, "isReference": true } ] }, { "name": "InputSet", "superClass": [ "BaseElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "dataInputRefs", "type": "DataInput", "isMany": true, "isReference": true }, { "name": "optionalInputRefs", "type": "DataInput", "isMany": true, "isReference": true }, { "name": "whileExecutingInputRefs", "type": "DataInput", "isMany": true, "isReference": true }, { "name": "outputSetRefs", "type": "OutputSet", "isMany": true, "isReference": true } ] }, { "name": "OutputSet", "superClass": [ "BaseElement" ], "properties": [ { "name": "dataOutputRefs", "type": "DataOutput", "isMany": true, "isReference": true }, { "name": "name", "isAttr": true, "type": "String" }, { "name": "inputSetRefs", "type": "InputSet", "isMany": true, "isReference": true }, { "name": "optionalOutputRefs", "type": "DataOutput", "isMany": true, "isReference": true }, { "name": "whileExecutingOutputRefs", "type": "DataOutput", "isMany": true, "isReference": true } ] }, { "name": "Property", "superClass": [ "ItemAwareElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" } ] }, { "name": "DataInputAssociation", "superClass": [ "DataAssociation" ] }, { "name": "DataOutputAssociation", "superClass": [ "DataAssociation" ] }, { "name": "InputOutputSpecification", "superClass": [ "BaseElement" ], "properties": [ { "name": "dataInputs", "type": "DataInput", "isMany": true }, { "name": "dataOutputs", "type": "DataOutput", "isMany": true }, { "name": "inputSets", "type": "InputSet", "isMany": true }, { "name": "outputSets", "type": "OutputSet", "isMany": true } ] }, { "name": "DataObject", "superClass": [ "FlowElement", "ItemAwareElement" ], "properties": [ { "name": "isCollection", "default": false, "isAttr": true, "type": "Boolean" } ] }, { "name": "InputOutputBinding", "properties": [ { "name": "inputDataRef", "type": "InputSet", "isAttr": true, "isReference": true }, { "name": "outputDataRef", "type": "OutputSet", "isAttr": true, "isReference": true }, { "name": "operationRef", "type": "Operation", "isAttr": true, "isReference": true } ] }, { "name": "Assignment", "superClass": [ "BaseElement" ], "properties": [ { "name": "from", "type": "Expression", "xml": { "serialize": "xsi:type" } }, { "name": "to", "type": "Expression", "xml": { "serialize": "xsi:type" } } ] }, { "name": "DataStore", "superClass": [ "RootElement", "ItemAwareElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "capacity", "isAttr": true, "type": "Integer" }, { "name": "isUnlimited", "default": true, "isAttr": true, "type": "Boolean" } ] }, { "name": "DataStoreReference", "superClass": [ "ItemAwareElement", "FlowElement" ], "properties": [ { "name": "dataStoreRef", "type": "DataStore", "isAttr": true, "isReference": true } ] }, { "name": "DataObjectReference", "superClass": [ "ItemAwareElement", "FlowElement" ], "properties": [ { "name": "dataObjectRef", "type": "DataObject", "isAttr": true, "isReference": true } ] }, { "name": "ConversationLink", "superClass": [ "BaseElement" ], "properties": [ { "name": "sourceRef", "type": "InteractionNode", "isAttr": true, "isReference": true }, { "name": "targetRef", "type": "InteractionNode", "isAttr": true, "isReference": true }, { "name": "name", "isAttr": true, "type": "String" } ] }, { "name": "ConversationAssociation", "superClass": [ "BaseElement" ], "properties": [ { "name": "innerConversationNodeRef", "type": "ConversationNode", "isAttr": true, "isReference": true }, { "name": "outerConversationNodeRef", "type": "ConversationNode", "isAttr": true, "isReference": true } ] }, { "name": "CallConversation", "superClass": [ "ConversationNode" ], "properties": [ { "name": "calledCollaborationRef", "type": "Collaboration", "isAttr": true, "isReference": true }, { "name": "participantAssociations", "type": "ParticipantAssociation", "isMany": true } ] }, { "name": "Conversation", "superClass": [ "ConversationNode" ] }, { "name": "SubConversation", "superClass": [ "ConversationNode" ], "properties": [ { "name": "conversationNodes", "type": "ConversationNode", "isMany": true } ] }, { "name": "ConversationNode", "isAbstract": true, "superClass": [ "InteractionNode", "BaseElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "participantRef", "type": "Participant", "isMany": true, "isReference": true }, { "name": "messageFlowRefs", "type": "MessageFlow", "isMany": true, "isReference": true }, { "name": "correlationKeys", "type": "CorrelationKey", "isMany": true } ] }, { "name": "GlobalConversation", "superClass": [ "Collaboration" ] }, { "name": "PartnerEntity", "superClass": [ "RootElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "participantRef", "type": "Participant", "isMany": true, "isReference": true } ] }, { "name": "PartnerRole", "superClass": [ "RootElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "participantRef", "type": "Participant", "isMany": true, "isReference": true } ] }, { "name": "CorrelationProperty", "superClass": [ "RootElement" ], "properties": [ { "name": "correlationPropertyRetrievalExpression", "type": "CorrelationPropertyRetrievalExpression", "isMany": true }, { "name": "name", "isAttr": true, "type": "String" }, { "name": "type", "type": "ItemDefinition", "isAttr": true, "isReference": true } ] }, { "name": "Error", "superClass": [ "RootElement" ], "properties": [ { "name": "structureRef", "type": "ItemDefinition", "isAttr": true, "isReference": true }, { "name": "name", "isAttr": true, "type": "String" }, { "name": "errorCode", "isAttr": true, "type": "String" } ] }, { "name": "CorrelationKey", "superClass": [ "BaseElement" ], "properties": [ { "name": "correlationPropertyRef", "type": "CorrelationProperty", "isMany": true, "isReference": true }, { "name": "name", "isAttr": true, "type": "String" } ] }, { "name": "Expression", "superClass": [ "BaseElement" ], "isAbstract": false, "properties": [ { "name": "body", "type": "String", "isBody": true } ] }, { "name": "FormalExpression", "superClass": [ "Expression" ], "properties": [ { "name": "language", "isAttr": true, "type": "String" }, { "name": "evaluatesToTypeRef", "type": "ItemDefinition", "isAttr": true, "isReference": true } ] }, { "name": "Message", "superClass": [ "RootElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "itemRef", "type": "ItemDefinition", "isAttr": true, "isReference": true } ] }, { "name": "ItemDefinition", "superClass": [ "RootElement" ], "properties": [ { "name": "itemKind", "type": "ItemKind", "isAttr": true }, { "name": "structureRef", "type": "String", "isAttr": true }, { "name": "isCollection", "default": false, "isAttr": true, "type": "Boolean" }, { "name": "import", "type": "Import", "isAttr": true, "isReference": true } ] }, { "name": "FlowElement", "isAbstract": true, "superClass": [ "BaseElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "auditing", "type": "Auditing" }, { "name": "monitoring", "type": "Monitoring" }, { "name": "categoryValueRef", "type": "CategoryValue", "isMany": true, "isReference": true } ] }, { "name": "SequenceFlow", "superClass": [ "FlowElement" ], "properties": [ { "name": "isImmediate", "isAttr": true, "type": "Boolean" }, { "name": "conditionExpression", "type": "Expression", "xml": { "serialize": "xsi:type" } }, { "name": "sourceRef", "type": "FlowNode", "isAttr": true, "isReference": true }, { "name": "targetRef", "type": "FlowNode", "isAttr": true, "isReference": true } ] }, { "name": "FlowElementsContainer", "isAbstract": true, "superClass": [ "BaseElement" ], "properties": [ { "name": "laneSets", "type": "LaneSet", "isMany": true }, { "name": "flowElements", "type": "FlowElement", "isMany": true } ] }, { "name": "CallableElement", "isAbstract": true, "superClass": [ "RootElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "ioSpecification", "type": "InputOutputSpecification", "xml": { "serialize": "property" } }, { "name": "supportedInterfaceRef", "type": "Interface", "isMany": true, "isReference": true }, { "name": "ioBinding", "type": "InputOutputBinding", "isMany": true, "xml": { "serialize": "property" } } ] }, { "name": "FlowNode", "isAbstract": true, "superClass": [ "FlowElement" ], "properties": [ { "name": "incoming", "type": "SequenceFlow", "isMany": true, "isReference": true }, { "name": "outgoing", "type": "SequenceFlow", "isMany": true, "isReference": true }, { "name": "lanes", "type": "Lane", "isVirtual": true, "isMany": true, "isReference": true } ] }, { "name": "CorrelationPropertyRetrievalExpression", "superClass": [ "BaseElement" ], "properties": [ { "name": "messagePath", "type": "FormalExpression" }, { "name": "messageRef", "type": "Message", "isAttr": true, "isReference": true } ] }, { "name": "CorrelationPropertyBinding", "superClass": [ "BaseElement" ], "properties": [ { "name": "dataPath", "type": "FormalExpression" }, { "name": "correlationPropertyRef", "type": "CorrelationProperty", "isAttr": true, "isReference": true } ] }, { "name": "Resource", "superClass": [ "RootElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "resourceParameters", "type": "ResourceParameter", "isMany": true } ] }, { "name": "ResourceParameter", "superClass": [ "BaseElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "isRequired", "isAttr": true, "type": "Boolean" }, { "name": "type", "type": "ItemDefinition", "isAttr": true, "isReference": true } ] }, { "name": "CorrelationSubscription", "superClass": [ "BaseElement" ], "properties": [ { "name": "correlationKeyRef", "type": "CorrelationKey", "isAttr": true, "isReference": true }, { "name": "correlationPropertyBinding", "type": "CorrelationPropertyBinding", "isMany": true } ] }, { "name": "MessageFlow", "superClass": [ "BaseElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "sourceRef", "type": "InteractionNode", "isAttr": true, "isReference": true }, { "name": "targetRef", "type": "InteractionNode", "isAttr": true, "isReference": true }, { "name": "messageRef", "type": "Message", "isAttr": true, "isReference": true } ] }, { "name": "MessageFlowAssociation", "superClass": [ "BaseElement" ], "properties": [ { "name": "innerMessageFlowRef", "type": "MessageFlow", "isAttr": true, "isReference": true }, { "name": "outerMessageFlowRef", "type": "MessageFlow", "isAttr": true, "isReference": true } ] }, { "name": "InteractionNode", "isAbstract": true, "properties": [ { "name": "incomingConversationLinks", "type": "ConversationLink", "isVirtual": true, "isMany": true, "isReference": true }, { "name": "outgoingConversationLinks", "type": "ConversationLink", "isVirtual": true, "isMany": true, "isReference": true } ] }, { "name": "Participant", "superClass": [ "InteractionNode", "BaseElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "interfaceRef", "type": "Interface", "isMany": true, "isReference": true }, { "name": "participantMultiplicity", "type": "ParticipantMultiplicity" }, { "name": "endPointRefs", "type": "EndPoint", "isMany": true, "isReference": true }, { "name": "processRef", "type": "Process", "isAttr": true, "isReference": true } ] }, { "name": "ParticipantAssociation", "superClass": [ "BaseElement" ], "properties": [ { "name": "innerParticipantRef", "type": "Participant", "isAttr": true, "isReference": true }, { "name": "outerParticipantRef", "type": "Participant", "isAttr": true, "isReference": true } ] }, { "name": "ParticipantMultiplicity", "properties": [ { "name": "minimum", "default": 0, "isAttr": true, "type": "Integer" }, { "name": "maximum", "default": 1, "isAttr": true, "type": "Integer" } ], "superClass": [ "BaseElement" ] }, { "name": "Collaboration", "superClass": [ "RootElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "isClosed", "isAttr": true, "type": "Boolean" }, { "name": "participants", "type": "Participant", "isMany": true }, { "name": "messageFlows", "type": "MessageFlow", "isMany": true }, { "name": "artifacts", "type": "Artifact", "isMany": true }, { "name": "conversations", "type": "ConversationNode", "isMany": true }, { "name": "conversationAssociations", "type": "ConversationAssociation" }, { "name": "participantAssociations", "type": "ParticipantAssociation", "isMany": true }, { "name": "messageFlowAssociations", "type": "MessageFlowAssociation", "isMany": true }, { "name": "correlationKeys", "type": "CorrelationKey", "isMany": true }, { "name": "choreographyRef", "type": "Choreography", "isMany": true, "isReference": true }, { "name": "conversationLinks", "type": "ConversationLink", "isMany": true } ] }, { "name": "ChoreographyActivity", "isAbstract": true, "superClass": [ "FlowNode" ], "properties": [ { "name": "participantRef", "type": "Participant", "isMany": true, "isReference": true }, { "name": "initiatingParticipantRef", "type": "Participant", "isAttr": true, "isReference": true }, { "name": "correlationKeys", "type": "CorrelationKey", "isMany": true }, { "name": "loopType", "type": "ChoreographyLoopType", "default": "None", "isAttr": true } ] }, { "name": "CallChoreography", "superClass": [ "ChoreographyActivity" ], "properties": [ { "name": "calledChoreographyRef", "type": "Choreography", "isAttr": true, "isReference": true }, { "name": "participantAssociations", "type": "ParticipantAssociation", "isMany": true } ] }, { "name": "SubChoreography", "superClass": [ "ChoreographyActivity", "FlowElementsContainer" ], "properties": [ { "name": "artifacts", "type": "Artifact", "isMany": true } ] }, { "name": "ChoreographyTask", "superClass": [ "ChoreographyActivity" ], "properties": [ { "name": "messageFlowRef", "type": "MessageFlow", "isMany": true, "isReference": true } ] }, { "name": "Choreography", "superClass": [ "Collaboration", "FlowElementsContainer" ] }, { "name": "GlobalChoreographyTask", "superClass": [ "Choreography" ], "properties": [ { "name": "initiatingParticipantRef", "type": "Participant", "isAttr": true, "isReference": true } ] }, { "name": "TextAnnotation", "superClass": [ "Artifact" ], "properties": [ { "name": "text", "type": "String" }, { "name": "textFormat", "default": "text/plain", "isAttr": true, "type": "String" } ] }, { "name": "Group", "superClass": [ "Artifact" ], "properties": [ { "name": "categoryValueRef", "type": "CategoryValue", "isAttr": true, "isReference": true } ] }, { "name": "Association", "superClass": [ "Artifact" ], "properties": [ { "name": "associationDirection", "type": "AssociationDirection", "isAttr": true }, { "name": "sourceRef", "type": "BaseElement", "isAttr": true, "isReference": true }, { "name": "targetRef", "type": "BaseElement", "isAttr": true, "isReference": true } ] }, { "name": "Category", "superClass": [ "RootElement" ], "properties": [ { "name": "categoryValue", "type": "CategoryValue", "isMany": true }, { "name": "name", "isAttr": true, "type": "String" } ] }, { "name": "Artifact", "isAbstract": true, "superClass": [ "BaseElement" ] }, { "name": "CategoryValue", "superClass": [ "BaseElement" ], "properties": [ { "name": "categorizedFlowElements", "type": "FlowElement", "isVirtual": true, "isMany": true, "isReference": true }, { "name": "value", "isAttr": true, "type": "String" } ] }, { "name": "Activity", "isAbstract": true, "superClass": [ "FlowNode" ], "properties": [ { "name": "isForCompensation", "default": false, "isAttr": true, "type": "Boolean" }, { "name": "default", "type": "SequenceFlow", "isAttr": true, "isReference": true }, { "name": "ioSpecification", "type": "InputOutputSpecification", "xml": { "serialize": "property" } }, { "name": "boundaryEventRefs", "type": "BoundaryEvent", "isMany": true, "isReference": true }, { "name": "properties", "type": "Property", "isMany": true }, { "name": "dataInputAssociations", "type": "DataInputAssociation", "isMany": true }, { "name": "dataOutputAssociations", "type": "DataOutputAssociation", "isMany": true }, { "name": "startQuantity", "default": 1, "isAttr": true, "type": "Integer" }, { "name": "resources", "type": "ResourceRole", "isMany": true }, { "name": "completionQuantity", "default": 1, "isAttr": true, "type": "Integer" }, { "name": "loopCharacteristics", "type": "LoopCharacteristics" } ] }, { "name": "ServiceTask", "superClass": [ "Task" ], "properties": [ { "name": "implementation", "isAttr": true, "type": "String" }, { "name": "operationRef", "type": "Operation", "isAttr": true, "isReference": true } ] }, { "name": "SubProcess", "superClass": [ "Activity", "FlowElementsContainer", "InteractionNode" ], "properties": [ { "name": "triggeredByEvent", "default": false, "isAttr": true, "type": "Boolean" }, { "name": "artifacts", "type": "Artifact", "isMany": true } ] }, { "name": "LoopCharacteristics", "isAbstract": true, "superClass": [ "BaseElement" ] }, { "name": "MultiInstanceLoopCharacteristics", "superClass": [ "LoopCharacteristics" ], "properties": [ { "name": "isSequential", "default": false, "isAttr": true, "type": "Boolean" }, { "name": "behavior", "type": "MultiInstanceBehavior", "default": "All", "isAttr": true }, { "name": "loopCardinality", "type": "Expression", "xml": { "serialize": "xsi:type" } }, { "name": "loopDataInputRef", "type": "ItemAwareElement", "isReference": true }, { "name": "loopDataOutputRef", "type": "ItemAwareElement", "isReference": true }, { "name": "inputDataItem", "type": "DataInput", "xml": { "serialize": "property" } }, { "name": "outputDataItem", "type": "DataOutput", "xml": { "serialize": "property" } }, { "name": "complexBehaviorDefinition", "type": "ComplexBehaviorDefinition", "isMany": true }, { "name": "completionCondition", "type": "Expression", "xml": { "serialize": "xsi:type" } }, { "name": "oneBehaviorEventRef", "type": "EventDefinition", "isAttr": true, "isReference": true }, { "name": "noneBehaviorEventRef", "type": "EventDefinition", "isAttr": true, "isReference": true } ] }, { "name": "StandardLoopCharacteristics", "superClass": [ "LoopCharacteristics" ], "properties": [ { "name": "testBefore", "default": false, "isAttr": true, "type": "Boolean" }, { "name": "loopCondition", "type": "Expression", "xml": { "serialize": "xsi:type" } }, { "name": "loopMaximum", "type": "Integer", "isAttr": true } ] }, { "name": "CallActivity", "superClass": [ "Activity" ], "properties": [ { "name": "calledElement", "type": "String", "isAttr": true } ] }, { "name": "Task", "superClass": [ "Activity", "InteractionNode" ] }, { "name": "SendTask", "superClass": [ "Task" ], "properties": [ { "name": "implementation", "isAttr": true, "type": "String" }, { "name": "operationRef", "type": "Operation", "isAttr": true, "isReference": true }, { "name": "messageRef", "type": "Message", "isAttr": true, "isReference": true } ] }, { "name": "ReceiveTask", "superClass": [ "Task" ], "properties": [ { "name": "implementation", "isAttr": true, "type": "String" }, { "name": "instantiate", "default": false, "isAttr": true, "type": "Boolean" }, { "name": "operationRef", "type": "Operation", "isAttr": true, "isReference": true }, { "name": "messageRef", "type": "Message", "isAttr": true, "isReference": true } ] }, { "name": "ScriptTask", "superClass": [ "Task" ], "properties": [ { "name": "scriptFormat", "isAttr": true, "type": "String" }, { "name": "script", "type": "String" } ] }, { "name": "BusinessRuleTask", "superClass": [ "Task" ], "properties": [ { "name": "implementation", "isAttr": true, "type": "String" } ] }, { "name": "AdHocSubProcess", "superClass": [ "SubProcess" ], "properties": [ { "name": "completionCondition", "type": "Expression", "xml": { "serialize": "xsi:type" } }, { "name": "ordering", "type": "AdHocOrdering", "isAttr": true }, { "name": "cancelRemainingInstances", "default": true, "isAttr": true, "type": "Boolean" } ] }, { "name": "Transaction", "superClass": [ "SubProcess" ], "properties": [ { "name": "protocol", "isAttr": true, "type": "String" }, { "name": "method", "isAttr": true, "type": "String" } ] }, { "name": "GlobalScriptTask", "superClass": [ "GlobalTask" ], "properties": [ { "name": "scriptLanguage", "isAttr": true, "type": "String" }, { "name": "script", "isAttr": true, "type": "String" } ] }, { "name": "GlobalBusinessRuleTask", "superClass": [ "GlobalTask" ], "properties": [ { "name": "implementation", "isAttr": true, "type": "String" } ] }, { "name": "ComplexBehaviorDefinition", "superClass": [ "BaseElement" ], "properties": [ { "name": "condition", "type": "FormalExpression" }, { "name": "event", "type": "ImplicitThrowEvent" } ] }, { "name": "ResourceRole", "superClass": [ "BaseElement" ], "properties": [ { "name": "resourceRef", "type": "Resource", "isReference": true }, { "name": "resourceParameterBindings", "type": "ResourceParameterBinding", "isMany": true }, { "name": "resourceAssignmentExpression", "type": "ResourceAssignmentExpression" }, { "name": "name", "isAttr": true, "type": "String" } ] }, { "name": "ResourceParameterBinding", "properties": [ { "name": "expression", "type": "Expression", "xml": { "serialize": "xsi:type" } }, { "name": "parameterRef", "type": "ResourceParameter", "isAttr": true, "isReference": true } ], "superClass": [ "BaseElement" ] }, { "name": "ResourceAssignmentExpression", "properties": [ { "name": "expression", "type": "Expression", "xml": { "serialize": "xsi:type" } } ], "superClass": [ "BaseElement" ] }, { "name": "Import", "properties": [ { "name": "importType", "isAttr": true, "type": "String" }, { "name": "location", "isAttr": true, "type": "String" }, { "name": "namespace", "isAttr": true, "type": "String" } ] }, { "name": "Definitions", "superClass": [ "BaseElement" ], "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "targetNamespace", "isAttr": true, "type": "String" }, { "name": "expressionLanguage", "default": "http://www.w3.org/1999/XPath", "isAttr": true, "type": "String" }, { "name": "typeLanguage", "default": "http://www.w3.org/2001/XMLSchema", "isAttr": true, "type": "String" }, { "name": "imports", "type": "Import", "isMany": true }, { "name": "extensions", "type": "Extension", "isMany": true }, { "name": "rootElements", "type": "RootElement", "isMany": true }, { "name": "diagrams", "isMany": true, "type": "bpmndi:BPMNDiagram" }, { "name": "exporter", "isAttr": true, "type": "String" }, { "name": "relationships", "type": "Relationship", "isMany": true }, { "name": "exporterVersion", "isAttr": true, "type": "String" } ] } ], "enumerations": [ { "name": "ProcessType", "literalValues": [ { "name": "None" }, { "name": "Public" }, { "name": "Private" } ] }, { "name": "GatewayDirection", "literalValues": [ { "name": "Unspecified" }, { "name": "Converging" }, { "name": "Diverging" }, { "name": "Mixed" } ] }, { "name": "EventBasedGatewayType", "literalValues": [ { "name": "Parallel" }, { "name": "Exclusive" } ] }, { "name": "RelationshipDirection", "literalValues": [ { "name": "None" }, { "name": "Forward" }, { "name": "Backward" }, { "name": "Both" } ] }, { "name": "ItemKind", "literalValues": [ { "name": "Physical" }, { "name": "Information" } ] }, { "name": "ChoreographyLoopType", "literalValues": [ { "name": "None" }, { "name": "Standard" }, { "name": "MultiInstanceSequential" }, { "name": "MultiInstanceParallel" } ] }, { "name": "AssociationDirection", "literalValues": [ { "name": "None" }, { "name": "One" }, { "name": "Both" } ] }, { "name": "MultiInstanceBehavior", "literalValues": [ { "name": "None" }, { "name": "One" }, { "name": "All" }, { "name": "Complex" } ] }, { "name": "AdHocOrdering", "literalValues": [ { "name": "Parallel" }, { "name": "Sequential" } ] } ], "prefix": "bpmn", "xml": { "tagAlias": "lowerCase", "typePrefix": "t" } } },{}],225:[function(require,module,exports){ module.exports={ "name": "BPMNDI", "uri": "http://www.omg.org/spec/BPMN/20100524/DI", "types": [ { "name": "BPMNDiagram", "properties": [ { "name": "plane", "type": "BPMNPlane", "redefines": "di:Diagram#rootElement" }, { "name": "labelStyle", "type": "BPMNLabelStyle", "isMany": true } ], "superClass": [ "di:Diagram" ] }, { "name": "BPMNPlane", "properties": [ { "name": "bpmnElement", "isAttr": true, "isReference": true, "type": "bpmn:BaseElement", "redefines": "di:DiagramElement#modelElement" } ], "superClass": [ "di:Plane" ] }, { "name": "BPMNShape", "properties": [ { "name": "bpmnElement", "isAttr": true, "isReference": true, "type": "bpmn:BaseElement", "redefines": "di:DiagramElement#modelElement" }, { "name": "isHorizontal", "isAttr": true, "type": "Boolean" }, { "name": "isExpanded", "isAttr": true, "type": "Boolean" }, { "name": "isMarkerVisible", "isAttr": true, "type": "Boolean" }, { "name": "label", "type": "BPMNLabel" }, { "name": "isMessageVisible", "isAttr": true, "type": "Boolean" }, { "name": "participantBandKind", "type": "ParticipantBandKind", "isAttr": true }, { "name": "choreographyActivityShape", "type": "BPMNShape", "isAttr": true, "isReference": true } ], "superClass": [ "di:LabeledShape" ] }, { "name": "BPMNEdge", "properties": [ { "name": "label", "type": "BPMNLabel" }, { "name": "bpmnElement", "isAttr": true, "isReference": true, "type": "bpmn:BaseElement", "redefines": "di:DiagramElement#modelElement" }, { "name": "sourceElement", "isAttr": true, "isReference": true, "type": "di:DiagramElement", "redefines": "di:Edge#source" }, { "name": "targetElement", "isAttr": true, "isReference": true, "type": "di:DiagramElement", "redefines": "di:Edge#target" }, { "name": "messageVisibleKind", "type": "MessageVisibleKind", "isAttr": true, "default": "initiating" } ], "superClass": [ "di:LabeledEdge" ] }, { "name": "BPMNLabel", "properties": [ { "name": "labelStyle", "type": "BPMNLabelStyle", "isAttr": true, "isReference": true, "redefines": "di:DiagramElement#style" } ], "superClass": [ "di:Label" ] }, { "name": "BPMNLabelStyle", "properties": [ { "name": "font", "type": "dc:Font" } ], "superClass": [ "di:Style" ] } ], "enumerations": [ { "name": "ParticipantBandKind", "literalValues": [ { "name": "top_initiating" }, { "name": "middle_initiating" }, { "name": "bottom_initiating" }, { "name": "top_non_initiating" }, { "name": "middle_non_initiating" }, { "name": "bottom_non_initiating" } ] }, { "name": "MessageVisibleKind", "literalValues": [ { "name": "initiating" }, { "name": "non_initiating" } ] } ], "associations": [], "prefix": "bpmndi" } },{}],226:[function(require,module,exports){ module.exports={ "name": "DC", "uri": "http://www.omg.org/spec/DD/20100524/DC", "types": [ { "name": "Boolean" }, { "name": "Integer" }, { "name": "Real" }, { "name": "String" }, { "name": "Font", "properties": [ { "name": "name", "type": "String", "isAttr": true }, { "name": "size", "type": "Real", "isAttr": true }, { "name": "isBold", "type": "Boolean", "isAttr": true }, { "name": "isItalic", "type": "Boolean", "isAttr": true }, { "name": "isUnderline", "type": "Boolean", "isAttr": true }, { "name": "isStrikeThrough", "type": "Boolean", "isAttr": true } ] }, { "name": "Point", "properties": [ { "name": "x", "type": "Real", "default": "0", "isAttr": true }, { "name": "y", "type": "Real", "default": "0", "isAttr": true } ] }, { "name": "Bounds", "properties": [ { "name": "x", "type": "Real", "default": "0", "isAttr": true }, { "name": "y", "type": "Real", "default": "0", "isAttr": true }, { "name": "width", "type": "Real", "isAttr": true }, { "name": "height", "type": "Real", "isAttr": true } ] } ], "prefix": "dc", "associations": [] } },{}],227:[function(require,module,exports){ module.exports={ "name": "DI", "uri": "http://www.omg.org/spec/DD/20100524/DI", "types": [ { "name": "DiagramElement", "isAbstract": true, "properties": [ { "name": "id", "type": "String", "isAttr": true, "isId": true }, { "name": "extension", "type": "Extension" }, { "name": "owningDiagram", "type": "Diagram", "isReadOnly": true, "isVirtual": true, "isReference": true }, { "name": "owningElement", "type": "DiagramElement", "isReadOnly": true, "isVirtual": true, "isReference": true }, { "name": "modelElement", "isReadOnly": true, "isVirtual": true, "isReference": true, "type": "Element" }, { "name": "style", "type": "Style", "isReadOnly": true, "isVirtual": true, "isReference": true }, { "name": "ownedElement", "type": "DiagramElement", "isReadOnly": true, "isVirtual": true, "isMany": true } ] }, { "name": "Node", "isAbstract": true, "superClass": [ "DiagramElement" ] }, { "name": "Edge", "isAbstract": true, "superClass": [ "DiagramElement" ], "properties": [ { "name": "source", "type": "DiagramElement", "isReadOnly": true, "isVirtual": true, "isReference": true }, { "name": "target", "type": "DiagramElement", "isReadOnly": true, "isVirtual": true, "isReference": true }, { "name": "waypoint", "isUnique": false, "isMany": true, "type": "dc:Point", "xml": { "serialize": "xsi:type" } } ] }, { "name": "Diagram", "isAbstract": true, "properties": [ { "name": "id", "type": "String", "isAttr": true, "isId": true }, { "name": "rootElement", "type": "DiagramElement", "isReadOnly": true, "isVirtual": true }, { "name": "name", "isAttr": true, "type": "String" }, { "name": "documentation", "isAttr": true, "type": "String" }, { "name": "resolution", "isAttr": true, "type": "Real" }, { "name": "ownedStyle", "type": "Style", "isReadOnly": true, "isVirtual": true, "isMany": true } ] }, { "name": "Shape", "isAbstract": true, "superClass": [ "Node" ], "properties": [ { "name": "bounds", "type": "dc:Bounds" } ] }, { "name": "Plane", "isAbstract": true, "superClass": [ "Node" ], "properties": [ { "name": "planeElement", "type": "DiagramElement", "subsettedProperty": "DiagramElement-ownedElement", "isMany": true } ] }, { "name": "LabeledEdge", "isAbstract": true, "superClass": [ "Edge" ], "properties": [ { "name": "ownedLabel", "type": "Label", "isReadOnly": true, "subsettedProperty": "DiagramElement-ownedElement", "isVirtual": true, "isMany": true } ] }, { "name": "LabeledShape", "isAbstract": true, "superClass": [ "Shape" ], "properties": [ { "name": "ownedLabel", "type": "Label", "isReadOnly": true, "subsettedProperty": "DiagramElement-ownedElement", "isVirtual": true, "isMany": true } ] }, { "name": "Label", "isAbstract": true, "superClass": [ "Node" ], "properties": [ { "name": "bounds", "type": "dc:Bounds" } ] }, { "name": "Style", "isAbstract": true, "properties": [ { "name": "id", "type": "String", "isAttr": true, "isId": true } ] }, { "name": "Extension", "properties": [ { "name": "values", "type": "Element", "isMany": true } ] } ], "associations": [], "prefix": "di", "xml": { "tagAlias": "lowerCase" } } },{}],228:[function(require,module,exports){ 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; // 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. var objectCreate = Object.create || objectCreatePolyfill; var objectKeys = Object.keys || objectKeysPolyfill; var bind = Function.prototype.bind || functionBindPolyfill; function EventEmitter() { if (!this._events || !Object.prototype.hasOwnProperty.call(this, '_events')) { this._events = objectCreate(null); this._eventsCount = 0; } 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. var defaultMaxListeners = 10; var hasDefineProperty; try { var o = {}; if (Object.defineProperty) Object.defineProperty(o, 'x', { value: 0 }); hasDefineProperty = o.x === 0; } catch (err) { hasDefineProperty = false; } if (hasDefineProperty) { Object.defineProperty(EventEmitter, 'defaultMaxListeners', { enumerable: true, get: function get() { return defaultMaxListeners; }, set: function set(arg) { // check whether the input is a positive number (whose value is zero or // greater and not a NaN). if (typeof arg !== 'number' || arg < 0 || arg !== arg) throw new TypeError('"defaultMaxListeners" must be a positive number'); defaultMaxListeners = arg; } }); } else { EventEmitter.defaultMaxListeners = defaultMaxListeners; } // 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 setMaxListeners(n) { if (typeof n !== 'number' || n < 0 || isNaN(n)) throw new TypeError('"n" argument must be a positive number'); this._maxListeners = n; return this; }; function $getMaxListeners(that) { if (that._maxListeners === undefined) return EventEmitter.defaultMaxListeners; return that._maxListeners; } EventEmitter.prototype.getMaxListeners = function getMaxListeners() { return $getMaxListeners(this); }; // These standalone emit* functions are used to optimize calling of event // handlers for fast cases because emit() itself often has a variable number of // arguments and can be deoptimized because of that. These functions always have // the same number of arguments and thus do not get deoptimized, so the code // inside them can execute faster. function emitNone(handler, isFn, self) { if (isFn) handler.call(self);else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) { listeners[i].call(self); } } } function emitOne(handler, isFn, self, arg1) { if (isFn) handler.call(self, arg1);else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) { listeners[i].call(self, arg1); } } } function emitTwo(handler, isFn, self, arg1, arg2) { if (isFn) handler.call(self, arg1, arg2);else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) { listeners[i].call(self, arg1, arg2); } } } function emitThree(handler, isFn, self, arg1, arg2, arg3) { if (isFn) handler.call(self, arg1, arg2, arg3);else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) { listeners[i].call(self, arg1, arg2, arg3); } } } function emitMany(handler, isFn, self, args) { if (isFn) handler.apply(self, args);else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) { listeners[i].apply(self, args); } } } EventEmitter.prototype.emit = function emit(type) { var er, handler, len, args, i, events; var doError = type === 'error'; events = this._events; if (events) doError = doError && events.error == null;else if (!doError) return false; // If there is no 'error' event listener then throw. if (doError) { if (arguments.length > 1) 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('Unhandled "error" event. (' + er + ')'); err.context = er; throw err; } return false; } handler = events[type]; if (!handler) return false; var isFn = typeof handler === 'function'; len = arguments.length; switch (len) { // fast cases case 1: emitNone(handler, isFn, this); break; case 2: emitOne(handler, isFn, this, arguments[1]); break; case 3: emitTwo(handler, isFn, this, arguments[1], arguments[2]); break; case 4: emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); break; // slower default: args = new Array(len - 1); for (i = 1; i < len; i++) { args[i - 1] = arguments[i]; }emitMany(handler, isFn, this, args); } return true; }; function _addListener(target, type, listener, prepend) { var m; var events; var existing; if (typeof listener !== 'function') throw new TypeError('"listener" argument must be a function'); events = target._events; if (!events) { events = target._events = objectCreate(null); target._eventsCount = 0; } else { // To avoid recursion in the case that type === "newListener"! Before // adding it to the listeners, first emit "newListener". if (events.newListener) { target.emit('newListener', type, listener.listener ? listener.listener : listener); // Re-assign `events` because a newListener handler could have caused the // this._events to be assigned to a new object events = target._events; } existing = events[type]; } if (!existing) { // Optimize the case of one listener. Don't need the extra array object. existing = events[type] = listener; ++target._eventsCount; } else { if (typeof existing === 'function') { // Adding the second element, need to change to array. existing = events[type] = prepend ? [listener, existing] : [existing, listener]; } else { // If we've already got an array, just append. if (prepend) { existing.unshift(listener); } else { existing.push(listener); } } // Check for listener leak if (!existing.warned) { m = $getMaxListeners(target); if (m && m > 0 && existing.length > m) { existing.warned = true; var w = new Error('Possible EventEmitter memory leak detected. ' + existing.length + ' "' + String(type) + '" listeners ' + 'added. Use emitter.setMaxListeners() to ' + 'increase limit.'); w.name = 'MaxListenersExceededWarning'; w.emitter = target; w.type = type; w.count = existing.length; if ((typeof console === 'undefined' ? 'undefined' : _typeof(console)) === 'object' && console.warn) { console.warn('%s: %s', w.name, w.message); } } } } return target; } EventEmitter.prototype.addListener = function addListener(type, listener) { return _addListener(this, type, listener, false); }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.prependListener = function prependListener(type, listener) { return _addListener(this, type, listener, true); }; function onceWrapper() { if (!this.fired) { this.target.removeListener(this.type, this.wrapFn); this.fired = true; switch (arguments.length) { case 0: return this.listener.call(this.target); case 1: return this.listener.call(this.target, arguments[0]); case 2: return this.listener.call(this.target, arguments[0], arguments[1]); case 3: return this.listener.call(this.target, arguments[0], arguments[1], arguments[2]); default: var args = new Array(arguments.length); for (var i = 0; i < args.length; ++i) { args[i] = arguments[i]; }this.listener.apply(this.target, args); } } } function _onceWrap(target, type, listener) { var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; var wrapped = bind.call(onceWrapper, state); wrapped.listener = listener; state.wrapFn = wrapped; return wrapped; } EventEmitter.prototype.once = function once(type, listener) { if (typeof listener !== 'function') throw new TypeError('"listener" argument must be a function'); this.on(type, _onceWrap(this, type, listener)); return this; }; EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) { if (typeof listener !== 'function') throw new TypeError('"listener" argument must be a function'); this.prependListener(type, _onceWrap(this, type, listener)); return this; }; // Emits a 'removeListener' event if and only if the listener was removed. EventEmitter.prototype.removeListener = function removeListener(type, listener) { var list, events, position, i, originalListener; if (typeof listener !== 'function') throw new TypeError('"listener" argument must be a function'); events = this._events; if (!events) return this; list = events[type]; if (!list) return this; if (list === listener || list.listener === listener) { if (--this._eventsCount === 0) this._events = objectCreate(null);else { delete events[type]; if (events.removeListener) this.emit('removeListener', type, list.listener || listener); } } else if (typeof list !== 'function') { position = -1; for (i = list.length - 1; i >= 0; i--) { if (list[i] === listener || list[i].listener === listener) { originalListener = list[i].listener; position = i; break; } } if (position < 0) return this; if (position === 0) list.shift();else spliceOne(list, position); if (list.length === 1) events[type] = list[0]; if (events.removeListener) this.emit('removeListener', type, originalListener || listener); } return this; }; EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) { var listeners, events, i; events = this._events; if (!events) return this; // not listening for removeListener, no need to emit if (!events.removeListener) { if (arguments.length === 0) { this._events = objectCreate(null); this._eventsCount = 0; } else if (events[type]) { if (--this._eventsCount === 0) this._events = objectCreate(null);else delete events[type]; } return this; } // emit removeListener for all listeners on all events if (arguments.length === 0) { var keys = objectKeys(events); var key; for (i = 0; i < keys.length; ++i) { key = keys[i]; if (key === 'removeListener') continue; this.removeAllListeners(key); } this.removeAllListeners('removeListener'); this._events = objectCreate(null); this._eventsCount = 0; return this; } listeners = events[type]; if (typeof listeners === 'function') { this.removeListener(type, listeners); } else if (listeners) { // LIFO order for (i = listeners.length - 1; i >= 0; i--) { this.removeListener(type, listeners[i]); } } return this; }; function _listeners(target, type, unwrap) { var events = target._events; if (!events) return []; var evlistener = events[type]; if (!evlistener) return []; if (typeof evlistener === 'function') return unwrap ? [evlistener.listener || evlistener] : [evlistener]; return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); } EventEmitter.prototype.listeners = function listeners(type) { return _listeners(this, type, true); }; EventEmitter.prototype.rawListeners = function rawListeners(type) { return _listeners(this, type, false); }; EventEmitter.listenerCount = function (emitter, type) { if (typeof emitter.listenerCount === 'function') { return emitter.listenerCount(type); } else { return listenerCount.call(emitter, type); } }; EventEmitter.prototype.listenerCount = listenerCount; function listenerCount(type) { var events = this._events; if (events) { var evlistener = events[type]; if (typeof evlistener === 'function') { return 1; } else if (evlistener) { return evlistener.length; } } return 0; } EventEmitter.prototype.eventNames = function eventNames() { return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; }; // About 1.5x faster than the two-arg version of Array#splice(). function spliceOne(list, index) { for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) { list[i] = list[k]; }list.pop(); } function arrayClone(arr, n) { var copy = new Array(n); for (var i = 0; i < n; ++i) { copy[i] = arr[i]; }return copy; } function unwrapListeners(arr) { var ret = new Array(arr.length); for (var i = 0; i < ret.length; ++i) { ret[i] = arr[i].listener || arr[i]; } return ret; } function objectCreatePolyfill(proto) { var F = function F() {}; F.prototype = proto; return new F(); } function objectKeysPolyfill(obj) { var keys = []; for (var k in obj) { if (Object.prototype.hasOwnProperty.call(obj, k)) { keys.push(k); } }return k; } function functionBindPolyfill(context) { var fn = this; return function () { return fn.apply(context, arguments); }; } },{}],229:[function(require,module,exports){ module.exports={ "name": "Camunda", "uri": "http://camunda.org/schema/1.0/bpmn", "prefix": "camunda", "xml": { "tagAlias": "lowerCase" }, "associations": [], "types": [ { "name": "InOutBinding", "superClass": [ "Element" ], "isAbstract": true, "properties": [ { "name": "source", "isAttr": true, "type": "String" }, { "name": "sourceExpression", "isAttr": true, "type": "String" }, { "name": "target", "isAttr": true, "type": "String" }, { "name": "businessKey", "isAttr": true, "type": "String" }, { "name": "local", "isAttr": true, "type": "Boolean", "default": false }, { "name": "variables", "isAttr": true, "type": "String" } ] }, { "name": "In", "superClass": [ "InOutBinding" ], "meta": { "allowedIn": [ "bpmn:CallActivity" ] } }, { "name": "Out", "superClass": [ "InOutBinding" ], "meta": { "allowedIn": [ "bpmn:CallActivity" ] } }, { "name": "AsyncCapable", "isAbstract": true, "extends": [ "bpmn:Activity", "bpmn:Gateway", "bpmn:Event" ], "properties": [ { "name": "async", "isAttr": true, "type": "Boolean", "default": false }, { "name": "asyncBefore", "isAttr": true, "type": "Boolean", "default": false }, { "name": "asyncAfter", "isAttr": true, "type": "Boolean", "default": false }, { "name": "exclusive", "isAttr": true, "type": "Boolean", "default": true } ] }, { "name": "JobPriorized", "isAbstract": true, "extends": [ "bpmn:Process", "camunda:AsyncCapable" ], "properties": [ { "name": "jobPriority", "isAttr": true, "type": "String" } ] }, { "name": "SignalEventDefinition", "isAbstract": true, "extends": [ "bpmn:SignalEventDefinition" ], "properties": [ { "name": "async", "isAttr": true, "type": "Boolean", "default": false } ] }, { "name": "ErrorEventDefinition", "isAbstract": true, "extends": [ "bpmn:ErrorEventDefinition" ], "properties": [ { "name": "errorCodeVariable", "isAttr": true, "type": "String" }, { "name": "errorMessageVariable", "isAttr": true, "type": "String" } ] }, { "name": "PotentialStarter", "superClass": [ "Element" ], "properties": [ { "name": "resourceAssignmentExpression", "type": "bpmn:ResourceAssignmentExpression" } ] }, { "name": "FormSupported", "isAbstract": true, "extends": [ "bpmn:StartEvent", "bpmn:UserTask" ], "properties": [ { "name": "formHandlerClass", "isAttr": true, "type": "String" }, { "name": "formKey", "isAttr": true, "type": "String" } ] }, { "name": "TemplateSupported", "isAbstract": true, "extends": [ "bpmn:Process", "bpmn:FlowElement" ], "properties": [ { "name": "modelerTemplate", "isAttr": true, "type": "String" } ] }, { "name": "Initiator", "isAbstract": true, "extends": [ "bpmn:StartEvent" ], "properties": [ { "name": "initiator", "isAttr": true, "type": "String" } ] }, { "name": "ScriptTask", "isAbstract": true, "extends": [ "bpmn:ScriptTask" ], "properties": [ { "name": "resultVariable", "isAttr": true, "type": "String" }, { "name": "resource", "isAttr": true, "type": "String" } ] }, { "name": "Process", "isAbstract": true, "extends": [ "bpmn:Process" ], "properties": [ { "name": "candidateStarterGroups", "isAttr": true, "type": "String" }, { "name": "candidateStarterUsers", "isAttr": true, "type": "String" }, { "name": "versionTag", "isAttr": true, "type": "String" }, { "name": "historyTimeToLive", "isAttr": true, "type": "String" }, { "name": "isStartableInTasklist", "isAttr": true, "type": "Boolean", "default": true } ] }, { "name": "EscalationEventDefinition", "isAbstract": true, "extends": [ "bpmn:EscalationEventDefinition" ], "properties": [ { "name": "escalationCodeVariable", "isAttr": true, "type": "String" } ] }, { "name": "FormalExpression", "isAbstract": true, "extends": [ "bpmn:FormalExpression" ], "properties": [ { "name": "resource", "isAttr": true, "type": "String" } ] }, { "name": "Assignable", "extends": [ "bpmn:UserTask" ], "properties": [ { "name": "assignee", "isAttr": true, "type": "String" }, { "name": "candidateUsers", "isAttr": true, "type": "String" }, { "name": "candidateGroups", "isAttr": true, "type": "String" }, { "name": "dueDate", "isAttr": true, "type": "String" }, { "name": "followUpDate", "isAttr": true, "type": "String" }, { "name": "priority", "isAttr": true, "type": "String" } ] }, { "name": "CallActivity", "extends": [ "bpmn:CallActivity" ], "properties": [ { "name": "calledElementBinding", "isAttr": true, "type": "String", "default": "latest" }, { "name": "calledElementVersion", "isAttr": true, "type": "String" }, { "name": "calledElementVersionTag", "isAttr": true, "type": "String" }, { "name": "calledElementTenantId", "isAttr": true, "type": "String" }, { "name": "caseRef", "isAttr": true, "type": "String" }, { "name": "caseBinding", "isAttr": true, "type": "String", "default": "latest" }, { "name": "caseVersion", "isAttr": true, "type": "String" }, { "name": "caseTenantId", "isAttr": true, "type": "String" }, { "name": "variableMappingClass", "isAttr": true, "type": "String" }, { "name": "variableMappingDelegateExpression", "isAttr": true, "type": "String" } ] }, { "name": "ServiceTaskLike", "extends": [ "bpmn:ServiceTask", "bpmn:BusinessRuleTask", "bpmn:SendTask", "bpmn:MessageEventDefinition" ], "properties": [ { "name": "expression", "isAttr": true, "type": "String" }, { "name": "class", "isAttr": true, "type": "String" }, { "name": "delegateExpression", "isAttr": true, "type": "String" }, { "name": "resultVariable", "isAttr": true, "type": "String" } ] }, { "name": "DmnCapable", "extends": [ "bpmn:BusinessRuleTask" ], "properties": [ { "name": "decisionRef", "isAttr": true, "type": "String" }, { "name": "decisionRefBinding", "isAttr": true, "type": "String", "default": "latest" }, { "name": "decisionRefVersion", "isAttr": true, "type": "String" }, { "name": "mapDecisionResult", "isAttr": true, "type": "String", "default": "resultList" }, { "name": "decisionRefTenantId", "isAttr": true, "type": "String" } ] }, { "name": "ExternalCapable", "extends": [ "camunda:ServiceTaskLike" ], "properties": [ { "name": "type", "isAttr": true, "type": "String" }, { "name": "topic", "isAttr": true, "type": "String" } ] }, { "name": "TaskPriorized", "extends": [ "bpmn:Process", "camunda:ExternalCapable" ], "properties": [ { "name": "taskPriority", "isAttr": true, "type": "String" } ] }, { "name": "Properties", "superClass": [ "Element" ], "meta": { "allowedIn": [ "*" ] }, "properties": [ { "name": "values", "type": "Property", "isMany": true } ] }, { "name": "Property", "superClass": [ "Element" ], "properties": [ { "name": "id", "type": "String", "isAttr": true }, { "name": "name", "type": "String", "isAttr": true }, { "name": "value", "type": "String", "isAttr": true } ] }, { "name": "Connector", "superClass": [ "Element" ], "meta": { "allowedIn": [ "bpmn:ServiceTask", "bpmn:BusinessRuleTask", "bpmn:SendTask" ] }, "properties": [ { "name": "inputOutput", "type": "InputOutput" }, { "name": "connectorId", "type": "String" } ] }, { "name": "InputOutput", "superClass": [ "Element" ], "meta": { "allowedIn": [ "bpmn:Task", "bpmn:UserTask", "bpmn:ServiceTask", "bpmn:SendTask", "bpmn:BusinessRuleTask", "bpmn:ReceiveTask", "bpmn:ScriptTask", "bpmn:ManualTask", "bpmn:GlobalUserTask", "bpmn:GlobalScriptTask", "bpmn:GlobalBusinessRuleTask", "bpmn:GlobalTask", "bpmn:GlobalManualTask", "bpmn:SubProcess", "bpmn:Transaction", "bpmn:IntermediateCatchEvent", "bpmn:IntermediateThrowEvent", "bpmn:EndEvent", "bpmn:ThrowEvent", "bpmn:CatchEvent", "bpmn:ImplicitThrowEvent", "bpmn:CallActivity" ] }, "properties": [ { "name": "inputOutput", "type": "InputOutput" }, { "name": "connectorId", "type": "String" }, { "name": "inputParameters", "isMany": true, "type": "InputParameter" }, { "name": "outputParameters", "isMany": true, "type": "OutputParameter" } ] }, { "name": "InputOutputParameter", "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "value", "isBody": true, "type": "String" }, { "name": "definition", "type": "InputOutputParameterDefinition" } ] }, { "name": "InputOutputParameterDefinition", "isAbstract": true }, { "name": "List", "superClass": [ "InputOutputParameterDefinition" ], "properties": [ { "name": "items", "isMany": true, "type": "InputOutputParameterDefinition" } ] }, { "name": "Map", "superClass": [ "InputOutputParameterDefinition" ], "properties": [ { "name": "entries", "isMany": true, "type": "Entry" } ] }, { "name": "Entry", "properties": [ { "name": "key", "isAttr": true, "type": "String" }, { "name": "value", "isBody": true, "type": "String" }, { "name": "definition", "type": "InputOutputParameterDefinition" } ] }, { "name": "Value", "superClass": [ "InputOutputParameterDefinition" ], "properties": [ { "name": "id", "isAttr": true, "type": "String" }, { "name": "name", "isAttr": true, "type": "String" }, { "name": "value", "isBody": true, "type": "String" } ] }, { "name": "Script", "superClass": [ "InputOutputParameterDefinition" ], "properties": [ { "name": "scriptFormat", "isAttr": true, "type": "String" }, { "name": "resource", "isAttr": true, "type": "String" }, { "name": "value", "isBody": true, "type": "String" } ] }, { "name": "Field", "superClass": [ "Element" ], "meta": { "allowedIn": [ "bpmn:ServiceTask", "bpmn:BusinessRuleTask", "bpmn:SendTask" ] }, "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "expression", "type": "String" }, { "name": "stringValue", "isAttr": true, "type": "String" }, { "name": "string", "type": "String" } ] }, { "name": "InputParameter", "superClass": [ "InputOutputParameter" ] }, { "name": "OutputParameter", "superClass": [ "InputOutputParameter" ] }, { "name": "Collectable", "isAbstract": true, "extends": [ "bpmn:MultiInstanceLoopCharacteristics" ], "superClass": [ "camunda:AsyncCapable" ], "properties": [ { "name": "collection", "isAttr": true, "type": "String" }, { "name": "elementVariable", "isAttr": true, "type": "String" } ] }, { "name": "FailedJobRetryTimeCycle", "superClass": [ "Element" ], "meta": { "allowedIn": [ "bpmn:Task", "bpmn:ServiceTask", "bpmn:SendTask", "bpmn:UserTask", "bpmn:BusinessRuleTask", "bpmn:ScriptTask", "bpmn:ReceiveTask", "bpmn:CallActivity", "bpmn:TimerEventDefinition", "bpmn:SignalEventDefinition", "bpmn:MultiInstanceLoopCharacteristics" ] }, "properties": [ { "name": "body", "isBody": true, "type": "String" } ] }, { "name": "ExecutionListener", "superClass": [ "Element" ], "meta": { "allowedIn": [ "bpmn:Task", "bpmn:ServiceTask", "bpmn:UserTask", "bpmn:BusinessRuleTask", "bpmn:ScriptTask", "bpmn:ReceiveTask", "bpmn:ManualTask", "bpmn:ExclusiveGateway", "bpmn:SequenceFlow", "bpmn:ParallelGateway", "bpmn:InclusiveGateway", "bpmn:EventBasedGateway", "bpmn:StartEvent", "bpmn:IntermediateCatchEvent", "bpmn:IntermediateThrowEvent", "bpmn:EndEvent", "bpmn:BoundaryEvent", "bpmn:CallActivity", "bpmn:SubProcess" ] }, "properties": [ { "name": "expression", "isAttr": true, "type": "String" }, { "name": "class", "isAttr": true, "type": "String" }, { "name": "delegateExpression", "isAttr": true, "type": "String" }, { "name": "event", "isAttr": true, "type": "String" }, { "name": "script", "type": "Script" }, { "name": "fields", "type": "Field", "isMany": true } ] }, { "name": "TaskListener", "superClass": [ "Element" ], "meta": { "allowedIn": [ "bpmn:UserTask" ] }, "properties": [ { "name": "expression", "isAttr": true, "type": "String" }, { "name": "class", "isAttr": true, "type": "String" }, { "name": "delegateExpression", "isAttr": true, "type": "String" }, { "name": "event", "isAttr": true, "type": "String" }, { "name": "script", "type": "Script" }, { "name": "fields", "type": "Field", "isMany": true } ] }, { "name": "FormProperty", "superClass": [ "Element" ], "meta": { "allowedIn": [ "bpmn:StartEvent", "bpmn:UserTask" ] }, "properties": [ { "name": "id", "type": "String", "isAttr": true }, { "name": "name", "type": "String", "isAttr": true }, { "name": "type", "type": "String", "isAttr": true }, { "name": "required", "type": "String", "isAttr": true }, { "name": "readable", "type": "String", "isAttr": true }, { "name": "writable", "type": "String", "isAttr": true }, { "name": "variable", "type": "String", "isAttr": true }, { "name": "expression", "type": "String", "isAttr": true }, { "name": "datePattern", "type": "String", "isAttr": true }, { "name": "default", "type": "String", "isAttr": true }, { "name": "values", "type": "Value", "isMany": true } ] }, { "name": "FormData", "superClass": [ "Element" ], "meta": { "allowedIn": [ "bpmn:StartEvent", "bpmn:UserTask" ] }, "properties": [ { "name": "fields", "type": "FormField", "isMany": true }, { "name": "businessKey", "type": "String", "isAttr": true } ] }, { "name": "FormField", "superClass": [ "Element" ], "properties": [ { "name": "id", "type": "String", "isAttr": true }, { "name": "label", "type": "String", "isAttr": true }, { "name": "type", "type": "String", "isAttr": true }, { "name": "datePattern", "type": "String", "isAttr": true }, { "name": "defaultValue", "type": "String", "isAttr": true }, { "name": "properties", "type": "Properties" }, { "name": "validation", "type": "Validation" }, { "name": "values", "type": "Value", "isMany": true } ] }, { "name": "Validation", "superClass": [ "Element" ], "properties": [ { "name": "constraints", "type": "Constraint", "isMany": true } ] }, { "name": "Constraint", "superClass": [ "Element" ], "properties": [ { "name": "name", "type": "String", "isAttr": true }, { "name": "config", "type": "String", "isAttr": true } ] }, { "name": "ConditionalEventDefinition", "isAbstract": true, "extends": [ "bpmn:ConditionalEventDefinition" ], "properties": [ { "name": "variableName", "isAttr": true, "type": "String" }, { "name": "variableEvent", "isAttr": true, "type": "String" } ] } ], "emumerations": [ ] } },{}],230:[function(require,module,exports){ 'use strict'; /** * Module dependencies. */ try { var index = require('indexof'); } catch (err) { var index = require('component-indexof'); } /** * Whitespace regexp. */ var re = /\s+/; /** * toString reference. */ var toString = Object.prototype.toString; /** * Wrap `el` in a `ClassList`. * * @param {Element} el * @return {ClassList} * @api public */ module.exports = function (el) { return new ClassList(el); }; /** * Initialize a new ClassList for `el`. * * @param {Element} el * @api private */ function ClassList(el) { if (!el || !el.nodeType) { throw new Error('A DOM element reference is required'); } this.el = el; this.list = el.classList; } /** * Add class `name` if not already present. * * @param {String} name * @return {ClassList} * @api public */ ClassList.prototype.add = function (name) { // classList if (this.list) { this.list.add(name); return this; } // fallback var arr = this.array(); var i = index(arr, name); if (!~i) arr.push(name); this.el.className = arr.join(' '); return this; }; /** * Remove class `name` when present, or * pass a regular expression to remove * any which match. * * @param {String|RegExp} name * @return {ClassList} * @api public */ ClassList.prototype.remove = function (name) { if ('[object RegExp]' == toString.call(name)) { return this.removeMatching(name); } // classList if (this.list) { this.list.remove(name); return this; } // fallback var arr = this.array(); var i = index(arr, name); if (~i) arr.splice(i, 1); this.el.className = arr.join(' '); return this; }; /** * Remove all classes matching `re`. * * @param {RegExp} re * @return {ClassList} * @api private */ ClassList.prototype.removeMatching = function (re) { var arr = this.array(); for (var i = 0; i < arr.length; i++) { if (re.test(arr[i])) { this.remove(arr[i]); } } return this; }; /** * Toggle class `name`, can force state via `force`. * * For browsers that support classList, but do not support `force` yet, * the mistake will be detected and corrected. * * @param {String} name * @param {Boolean} force * @return {ClassList} * @api public */ ClassList.prototype.toggle = function (name, force) { // classList if (this.list) { if ("undefined" !== typeof force) { if (force !== this.list.toggle(name, force)) { this.list.toggle(name); // toggle again to correct } } else { this.list.toggle(name); } return this; } // fallback if ("undefined" !== typeof force) { if (!force) { this.remove(name); } else { this.add(name); } } else { if (this.has(name)) { this.remove(name); } else { this.add(name); } } return this; }; /** * Return an array of classes. * * @return {Array} * @api public */ ClassList.prototype.array = function () { var className = this.el.getAttribute('class') || ''; var str = className.replace(/^\s+|\s+$/g, ''); var arr = str.split(re); if ('' === arr[0]) arr.shift(); return arr; }; /** * Check if class `name` is present. * * @param {String} name * @return {ClassList} * @api public */ ClassList.prototype.has = ClassList.prototype.contains = function (name) { return this.list ? this.list.contains(name) : !!~index(this.array(), name); }; },{"component-indexof":234,"indexof":234}],231:[function(require,module,exports){ 'use strict'; var matches = require('matches-selector'); module.exports = function (element, selector, checkYoSelf, root) { element = checkYoSelf ? { parentNode: element } : element; root = root || document; // Make sure `element !== document` and `element != null` // otherwise we get an illegal invocation while ((element = element.parentNode) && element !== document) { if (matches(element, selector)) return element; // After `matches` on the edge case that // the selector matches the root // (when the root is not the document) if (element === root) return; } }; },{"matches-selector":235}],232:[function(require,module,exports){ 'use strict'; /** * Module dependencies. */ try { var closest = require('closest'); } catch (err) { var closest = require('component-closest'); } try { var event = require('event'); } catch (err) { var event = require('component-event'); } /** * Delegate event `type` to `selector` * and invoke `fn(e)`. A callback function * is returned which may be passed to `.unbind()`. * * @param {Element} el * @param {String} selector * @param {String} type * @param {Function} fn * @param {Boolean} capture * @return {Function} * @api public */ exports.bind = function (el, selector, type, fn, capture) { return event.bind(el, type, function (e) { var target = e.target || e.srcElement; e.delegateTarget = closest(target, selector, true, el); if (e.delegateTarget) fn.call(el, e); }, capture); }; /** * Unbind event `type`'s callback `fn`. * * @param {Element} el * @param {String} type * @param {Function} fn * @param {Boolean} capture * @api public */ exports.unbind = function (el, type, fn, capture) { event.unbind(el, type, fn, capture); }; },{"closest":231,"component-closest":231,"component-event":233,"event":233}],233:[function(require,module,exports){ 'use strict'; var bind = window.addEventListener ? 'addEventListener' : 'attachEvent', unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent', prefix = bind !== 'addEventListener' ? 'on' : ''; /** * Bind `el` event `type` to `fn`. * * @param {Element} el * @param {String} type * @param {Function} fn * @param {Boolean} capture * @return {Function} * @api public */ exports.bind = function (el, type, fn, capture) { el[bind](prefix + type, fn, capture || false); return fn; }; /** * Unbind `el` event `type`'s callback `fn`. * * @param {Element} el * @param {String} type * @param {Function} fn * @param {Boolean} capture * @return {Function} * @api public */ exports.unbind = function (el, type, fn, capture) { el[unbind](prefix + type, fn, capture || false); return fn; }; },{}],234:[function(require,module,exports){ "use strict"; module.exports = function (arr, obj) { if (arr.indexOf) return arr.indexOf(obj); for (var i = 0; i < arr.length; ++i) { if (arr[i] === obj) return i; } return -1; }; },{}],235:[function(require,module,exports){ 'use strict'; /** * Module dependencies. */ try { var query = require('query'); } catch (err) { var query = require('component-query'); } /** * Element prototype. */ var proto = Element.prototype; /** * Vendor function. */ var vendor = proto.matches || proto.webkitMatchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || proto.oMatchesSelector; /** * Expose `match()`. */ module.exports = match; /** * Match `el` to `selector`. * * @param {Element} el * @param {String} selector * @return {Boolean} * @api public */ function match(el, selector) { if (!el || el.nodeType !== 1) return false; if (vendor) return vendor.call(el, selector); var nodes = query.all(selector, el.parentNode); for (var i = 0; i < nodes.length; ++i) { if (nodes[i] == el) return true; } return false; } },{"component-query":236,"query":236}],236:[function(require,module,exports){ 'use strict'; function one(selector, el) { return el.querySelector(selector); } exports = module.exports = function (selector, el) { el = el || document; return one(selector, el); }; exports.all = function (selector, el) { el = el || document; return el.querySelectorAll(selector); }; exports.engine = function (obj) { if (!obj.one) throw new Error('.one callback required'); if (!obj.all) throw new Error('.all callback required'); one = obj.one; exports.all = obj.all; return exports; }; },{}],237:[function(require,module,exports){ (function (global){ 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /*! https://mths.be/cssescape v1.5.1 by @mathias | MIT license */ ;(function (root, factory) { // https://github.com/umdjs/umd/blob/master/returnExports.js if ((typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) == 'object') { // For Node.js. module.exports = factory(root); } else if (typeof define == 'function' && define.amd) { // For AMD. Register as an anonymous module. define([], factory.bind(root, root)); } else { // For browser globals (not exposing the function separately). factory(root); } })(typeof global != 'undefined' ? global : undefined, function (root) { if (root.CSS && root.CSS.escape) { return root.CSS.escape; } // https://drafts.csswg.org/cssom/#serialize-an-identifier var cssEscape = function cssEscape(value) { if (arguments.length == 0) { throw new TypeError('`CSS.escape` requires an argument.'); } var string = String(value); var length = string.length; var index = -1; var codeUnit; var result = ''; var firstCodeUnit = string.charCodeAt(0); while (++index < length) { codeUnit = string.charCodeAt(index); // Note: there’s no need to special-case astral symbols, surrogate // pairs, or lone surrogates. // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER // (U+FFFD). if (codeUnit == 0x0000) { result += '\uFFFD'; continue; } if ( // If the character is in the range [\1-\1F] (U+0001 to U+001F) or is // U+007F, […] codeUnit >= 0x0001 && codeUnit <= 0x001F || codeUnit == 0x007F || // If the character is the first character and is in the range [0-9] // (U+0030 to U+0039), […] index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039 || // If the character is the second character and is in the range [0-9] // (U+0030 to U+0039) and the first character is a `-` (U+002D), […] index == 1 && codeUnit >= 0x0030 && codeUnit <= 0x0039 && firstCodeUnit == 0x002D) { // https://drafts.csswg.org/cssom/#escape-a-character-as-code-point result += '\\' + codeUnit.toString(16) + ' '; continue; } if ( // If the character is the first character and is a `-` (U+002D), and // there is no second character, […] index == 0 && length == 1 && codeUnit == 0x002D) { result += '\\' + string.charAt(index); continue; } // If the character is not handled by one of the above rules and is // greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or // is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to // U+005A), or [a-z] (U+0061 to U+007A), […] if (codeUnit >= 0x0080 || codeUnit == 0x002D || codeUnit == 0x005F || codeUnit >= 0x0030 && codeUnit <= 0x0039 || codeUnit >= 0x0041 && codeUnit <= 0x005A || codeUnit >= 0x0061 && codeUnit <= 0x007A) { // the character itself result += string.charAt(index); continue; } // Otherwise, the escaped character. // https://drafts.csswg.org/cssom/#escape-a-character result += '\\' + string.charAt(index); } return result; }; if (!root.CSS) { root.CSS = {}; } root.CSS.escape = cssEscape; return cssEscape; }); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],238:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _interactionEvents = require('diagram-js/lib/features/interaction-events'); var _interactionEvents2 = _interopRequireDefault(_interactionEvents); var _DirectEditing = require('./lib/DirectEditing'); var _DirectEditing2 = _interopRequireDefault(_DirectEditing); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_interactionEvents2.default], __init__: ['directEditing'], directEditing: ['type', _DirectEditing2.default] }; },{"./lib/DirectEditing":239,"diagram-js/lib/features/interaction-events":294}],239:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DirectEditing; var _minDash = require('min-dash'); var _TextBox = require('./TextBox'); var _TextBox2 = _interopRequireDefault(_TextBox); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A direct editing component that allows users * to edit an elements text directly in the diagram * * @param {EventBus} eventBus the event bus */ function DirectEditing(eventBus, canvas) { this._eventBus = eventBus; this._providers = []; this._textbox = new _TextBox2.default({ container: canvas.getContainer(), keyHandler: (0, _minDash.bind)(this._handleKey, this), resizeHandler: (0, _minDash.bind)(this._handleResize, this) }); } DirectEditing.$inject = ['eventBus', 'canvas']; /** * Register a direct editing provider * @param {Object} provider the provider, must expose an #activate(element) method that returns * an activation context ({ bounds: {x, y, width, height }, text }) if * direct editing is available for the given element. * Additionally the provider must expose a #update(element, value) method * to receive direct editing updates. */ DirectEditing.prototype.registerProvider = function (provider) { this._providers.push(provider); }; /** * Returns true if direct editing is currently active * * @return {Boolean} */ DirectEditing.prototype.isActive = function () { return !!this._active; }; /** * Cancel direct editing, if it is currently active */ DirectEditing.prototype.cancel = function () { if (!this._active) { return; } this._fire('cancel'); this.close(); }; DirectEditing.prototype._fire = function (event, context) { this._eventBus.fire('directEditing.' + event, context || { active: this._active }); }; DirectEditing.prototype.close = function () { this._textbox.destroy(); this._fire('deactivate'); this._active = null; this.resizable = undefined; }; DirectEditing.prototype.complete = function () { var active = this._active; if (!active) { return; } var text = this.getValue(); var bounds = this.$textbox.getBoundingClientRect(); if (text !== active.context.text || this.resizable) { active.provider.update(active.element, text, active.context.text, { x: bounds.top, y: bounds.left, width: bounds.width, height: bounds.height }); } this._fire('complete'); this.close(); }; DirectEditing.prototype.getValue = function () { return this._textbox.getValue(); }; DirectEditing.prototype._handleKey = function (e) { // stop bubble e.stopPropagation(); var key = e.keyCode || e.charCode; // ESC if (key === 27) { e.preventDefault(); return this.cancel(); } // Enter if (key === 13 && !e.shiftKey) { e.preventDefault(); return this.complete(); } }; DirectEditing.prototype._handleResize = function (event) { this._fire('resize', event); }; /** * Activate direct editing on the given element * * @param {Object} ElementDescriptor the descriptor for a shape or connection * @return {Boolean} true if the activation was possible */ DirectEditing.prototype.activate = function (element) { if (this.isActive()) { this.cancel(); } // the direct editing context var context; var provider = (0, _minDash.find)(this._providers, function (p) { return (context = p.activate(element)) ? p : null; }); // check if activation took place if (context) { this.$textbox = this._textbox.create(context.bounds, context.style, context.text, context.options); this._active = { element: element, context: context, provider: provider }; if (context.options && context.options.resizable) { this.resizable = true; } this._fire('activate'); } return !!context; }; },{"./TextBox":240,"min-dash":505}],240:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = TextBox; var _minDash = require('min-dash'); var _minDom = require('min-dom'); var min = Math.min, max = Math.max; function preventDefault(e) { e.preventDefault(); } function stopPropagation(e) { e.stopPropagation(); } function isTextNode(node) { return node.nodeType === Node.TEXT_NODE; } function toArray(nodeList) { return [].slice.call(nodeList); } /** * Initializes a container for a content editable div. * * Structure: * * container * parent * content * resize-handle * * @param {object} options * @param {DOMElement} options.container The DOM element to append the contentContainer to * @param {Function} options.keyHandler Handler for key events * @param {Function} options.resizeHandler Handler for resize events */ function TextBox(options) { this.container = options.container; this.parent = (0, _minDom.domify)('
' + '
' + '
'); this.content = (0, _minDom.query)('[contenteditable]', this.parent); this.keyHandler = options.keyHandler || function () {}; this.resizeHandler = options.resizeHandler || function () {}; this.autoResize = (0, _minDash.bind)(this.autoResize, this); this.handlePaste = (0, _minDash.bind)(this.handlePaste, this); } /** * Create a text box with the given position, size, style and text content * * @param {Object} bounds * @param {Number} bounds.x absolute x position * @param {Number} bounds.y absolute y position * @param {Number} [bounds.width] fixed width value * @param {Number} [bounds.height] fixed height value * @param {Number} [bounds.maxWidth] maximum width value * @param {Number} [bounds.maxHeight] maximum height value * @param {Number} [bounds.minWidth] minimum width value * @param {Number} [bounds.minHeight] minimum height value * @param {Object} [style] * @param {String} value text content * * @return {DOMElement} The created content DOM element */ TextBox.prototype.create = function (bounds, style, value, options) { var self = this; var parent = this.parent, content = this.content, container = this.container; options = this.options = options || {}; style = this.style = style || {}; var parentStyle = (0, _minDash.pick)(style, ['width', 'height', 'maxWidth', 'maxHeight', 'minWidth', 'minHeight', 'left', 'top', 'backgroundColor', 'position', 'overflow', 'border', 'wordWrap', 'textAlign', 'outline', 'transform']); (0, _minDash.assign)(parent.style, { width: bounds.width + 'px', height: bounds.height + 'px', maxWidth: bounds.maxWidth + 'px', maxHeight: bounds.maxHeight + 'px', minWidth: bounds.minWidth + 'px', minHeight: bounds.minHeight + 'px', left: bounds.x + 'px', top: bounds.y + 'px', backgroundColor: '#ffffff', position: 'absolute', overflow: 'visible', border: '1px solid #ccc', boxSizing: 'border-box', wordWrap: 'normal', textAlign: 'center', outline: 'none' }, parentStyle); var contentStyle = (0, _minDash.pick)(style, ['fontFamily', 'fontSize', 'fontWeight', 'lineHeight', 'padding', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft']); (0, _minDash.assign)(content.style, { boxSizing: 'border-box', width: '100%', outline: 'none', wordWrap: 'break-word' }, contentStyle); if (options.centerVertically) { (0, _minDash.assign)(content.style, { position: 'absolute', top: '50%', transform: 'translate(0, -50%)' }, contentStyle); } content.innerText = value; _minDom.event.bind(content, 'keydown', this.keyHandler); _minDom.event.bind(content, 'mousedown', stopPropagation); _minDom.event.bind(content, 'paste', self.handlePaste); if (options.autoResize) { _minDom.event.bind(content, 'input', this.autoResize); } if (options.resizable) { this.resizable(style); } container.appendChild(parent); // set selection to end of text this.setSelection(content.lastChild, content.lastChild && content.lastChild.length); return parent; }; /** * Intercept paste events to remove formatting from pasted text. */ TextBox.prototype.handlePaste = function (e) { var self = this; var options = this.options, style = this.style; e.preventDefault(); var text; if (e.clipboardData) { // Chrome, Firefox, Safari text = e.clipboardData.getData('text/plain'); } else { // Internet Explorer text = window.clipboardData.getData('Text'); } // insertHTML command not supported by Internet Explorer var success = document.execCommand('insertHTML', false, text); if (!success) { // Internet Explorer var range = this.getSelection(), startContainer = range.startContainer, endContainer = range.endContainer, startOffset = range.startOffset, endOffset = range.endOffset, commonAncestorContainer = range.commonAncestorContainer; var childNodesArray = toArray(commonAncestorContainer.childNodes); var container, offset; if (isTextNode(commonAncestorContainer)) { var containerTextContent = startContainer.textContent; startContainer.textContent = containerTextContent.substring(0, startOffset) + text + containerTextContent.substring(endOffset); container = startContainer; offset = startOffset + text.length; } else if (startContainer === this.content && endContainer === this.content) { var textNode = document.createTextNode(text); this.content.insertBefore(textNode, childNodesArray[startOffset]); container = textNode; offset = textNode.textContent.length; } else { var startContainerChildIndex = childNodesArray.indexOf(startContainer), endContainerChildIndex = childNodesArray.indexOf(endContainer); childNodesArray.forEach(function (childNode, index) { if (index === startContainerChildIndex) { childNode.textContent = startContainer.textContent.substring(0, startOffset) + text + endContainer.textContent.substring(endOffset); } else if (index > startContainerChildIndex && index <= endContainerChildIndex) { (0, _minDom.remove)(childNode); } }); container = startContainer; offset = startOffset + text.length; } if (container && offset !== undefined) { // is necessary in Internet Explorer setTimeout(function () { self.setSelection(container, offset); }); } } if (options.autoResize) { var hasResized = this.autoResize(style); if (hasResized) { this.resizeHandler(hasResized); } } }; /** * Automatically resize element vertically to fit its content. */ TextBox.prototype.autoResize = function () { var parent = this.parent, content = this.content; var fontSize = parseInt(this.style.fontSize) || 12; if (content.scrollHeight > parent.offsetHeight || content.scrollHeight < parent.offsetHeight - fontSize) { var bounds = parent.getBoundingClientRect(); var height = content.scrollHeight; parent.style.height = height + 'px'; this.resizeHandler({ width: bounds.width, height: bounds.height, dx: 0, dy: height - bounds.height }); } }; /** * Make an element resizable by adding a resize handle. */ TextBox.prototype.resizable = function () { var self = this; var parent = this.parent, resizeHandle = this.resizeHandle; var minWidth = parseInt(this.style.minWidth) || 0, minHeight = parseInt(this.style.minHeight) || 0, maxWidth = parseInt(this.style.maxWidth) || Infinity, maxHeight = parseInt(this.style.maxHeight) || Infinity; if (!resizeHandle) { resizeHandle = this.resizeHandle = (0, _minDom.domify)('
'); var startX, startY, startWidth, startHeight; var onMouseDown = function onMouseDown(e) { preventDefault(e); stopPropagation(e); startX = e.clientX; startY = e.clientY; var bounds = parent.getBoundingClientRect(); startWidth = bounds.width; startHeight = bounds.height; _minDom.event.bind(document, 'mousemove', onMouseMove); _minDom.event.bind(document, 'mouseup', onMouseUp); }; var onMouseMove = function onMouseMove(e) { preventDefault(e); stopPropagation(e); var newWidth = min(max(startWidth + e.clientX - startX, minWidth), maxWidth); var newHeight = min(max(startHeight + e.clientY - startY, minHeight), maxHeight); parent.style.width = newWidth + 'px'; parent.style.height = newHeight + 'px'; self.resizeHandler({ width: startWidth, height: startHeight, dx: e.clientX - startX, dy: e.clientY - startY }); }; var onMouseUp = function onMouseUp(e) { preventDefault(e); stopPropagation(e); _minDom.event.unbind(document, 'mousemove', onMouseMove, false); _minDom.event.unbind(document, 'mouseup', onMouseUp, false); }; _minDom.event.bind(resizeHandle, 'mousedown', onMouseDown); } (0, _minDash.assign)(resizeHandle.style, { position: 'absolute', bottom: '0px', right: '0px', cursor: 'nwse-resize', width: '0', height: '0', borderTop: (parseInt(this.style.fontSize) / 4 || 3) + 'px solid transparent', borderRight: (parseInt(this.style.fontSize) / 4 || 3) + 'px solid #ccc', borderBottom: (parseInt(this.style.fontSize) / 4 || 3) + 'px solid #ccc', borderLeft: (parseInt(this.style.fontSize) / 4 || 3) + 'px solid transparent' }); parent.appendChild(resizeHandle); }; /** * Clear content and style of the textbox, unbind listeners and * reset CSS style. */ TextBox.prototype.destroy = function () { var parent = this.parent, content = this.content, resizeHandle = this.resizeHandle; // clear content content.innerText = ''; // clear styles parent.removeAttribute('style'); content.removeAttribute('style'); _minDom.event.unbind(content, 'keydown', this.keyHandler); _minDom.event.unbind(content, 'mousedown', stopPropagation); _minDom.event.unbind(content, 'input', this.autoResize); _minDom.event.unbind(content, 'paste', this.handlePaste); if (resizeHandle) { resizeHandle.removeAttribute('style'); (0, _minDom.remove)(resizeHandle); } (0, _minDom.remove)(parent); }; TextBox.prototype.getValue = function () { return this.content.innerText; }; TextBox.prototype.getSelection = function () { var selection = window.getSelection(), range = selection.getRangeAt(0); return range; }; TextBox.prototype.setSelection = function (container, offset) { var range = document.createRange(); if (container === null) { range.selectNodeContents(this.content); } else { range.setStart(container, offset); range.setEnd(container, offset); } var selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); }; },{"min-dash":505,"min-dom":506}],241:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _Diagram = require('./lib/Diagram'); Object.defineProperty(exports, 'default', { enumerable: true, get: function get() { return _interopRequireDefault(_Diagram).default; } }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } },{"./lib/Diagram":242}],242:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Diagram; var _didi = require('didi'); var _core = require('./core'); var _core2 = _interopRequireDefault(_core); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Bootstrap an injector from a list of modules, instantiating a number of default components * * @ignore * @param {Array} bootstrapModules * * @return {didi.Injector} a injector to use to access the components */ function bootstrap(bootstrapModules) { var modules = [], components = []; function hasModule(m) { return modules.indexOf(m) >= 0; } function addModule(m) { modules.push(m); } function visit(m) { if (hasModule(m)) { return; } (m.__depends__ || []).forEach(visit); if (hasModule(m)) { return; } addModule(m); (m.__init__ || []).forEach(function (c) { components.push(c); }); } bootstrapModules.forEach(visit); var injector = new _didi.Injector(modules); components.forEach(function (c) { try { // eagerly resolve component (fn or string) injector[typeof c === 'string' ? 'get' : 'invoke'](c); } catch (e) { console.error('Failed to instantiate component'); console.error(e.stack); throw e; } }); return injector; } /** * Creates an injector from passed options. * * @ignore * @param {Object} options * @return {didi.Injector} */ function createInjector(options) { options = options || {}; var configModule = { 'config': ['value', options] }; var modules = [configModule, _core2.default].concat(options.modules || []); return bootstrap(modules); } /** * The main diagram-js entry point that bootstraps the diagram with the given * configuration. * * To register extensions with the diagram, pass them as Array to the constructor. * * @class djs.Diagram * @memberOf djs * @constructor * * @example * * Creating a plug-in that logs whenever a shape is added to the canvas. * * // plug-in implemenentation * function MyLoggingPlugin(eventBus) { * eventBus.on('shape.added', function(event) { * console.log('shape ', event.shape, ' was added to the diagram'); * }); * } * * // export as module * export default { * __init__: [ 'myLoggingPlugin' ], * myLoggingPlugin: [ 'type', MyLoggingPlugin ] * }; * * * // instantiate the diagram with the new plug-in * * import MyLoggingModule from 'path-to-my-logging-plugin'; * * var diagram = new Diagram({ * modules: [ * MyLoggingModule * ] * }); * * diagram.invoke([ 'canvas', function(canvas) { * // add shape to drawing canvas * canvas.addShape({ x: 10, y: 10 }); * }); * * // 'shape ... was added to the diagram' logged to console * * @param {Object} options * @param {Array} [options.modules] external modules to instantiate with the diagram * @param {didi.Injector} [injector] an (optional) injector to bootstrap the diagram with */ function Diagram(options, injector) { // create injector unless explicitly specified this.injector = injector = injector || createInjector(options); // API /** * Resolves a diagram service * * @method Diagram#get * * @param {String} name the name of the diagram service to be retrieved * @param {Boolean} [strict=true] if false, resolve missing services to null */ this.get = injector.get; /** * Executes a function into which diagram services are injected * * @method Diagram#invoke * * @param {Function|Object[]} fn the function to resolve * @param {Object} locals a number of locals to use to resolve certain dependencies */ this.invoke = injector.invoke; // init // indicate via event /** * An event indicating that all plug-ins are loaded. * * Use this event to fire other events to interested plug-ins * * @memberOf Diagram * * @event diagram.init * * @example * * eventBus.on('diagram.init', function() { * eventBus.fire('my-custom-event', { foo: 'BAR' }); * }); * * @type {Object} */ this.get('eventBus').fire('diagram.init'); } /** * Destroys the diagram * * @method Diagram#destroy */ Diagram.prototype.destroy = function () { this.get('eventBus').fire('diagram.destroy'); }; /** * Clear the diagram, removing all contents. */ Diagram.prototype.clear = function () { this.get('eventBus').fire('diagram.clear'); }; },{"./core":251,"didi":410}],243:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CommandInterceptor; var _minDash = require('min-dash'); var DEFAULT_PRIORITY = 1000; /** * A utility that can be used to plug-in into the command execution for * extension and/or validation. * * @param {EventBus} eventBus * * @example * * import inherits from 'inherits'; * * import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor'; * * function CommandLogger(eventBus) { * CommandInterceptor.call(this, eventBus); * * this.preExecute(function(event) { * console.log('command pre-execute', event); * }); * } * * inherits(CommandLogger, CommandInterceptor); * */ function CommandInterceptor(eventBus) { this._eventBus = eventBus; } CommandInterceptor.$inject = ['eventBus']; function unwrapEvent(fn, that) { return function (event) { return fn.call(that || null, event.context, event.command, event); }; } /** * Register an interceptor for a command execution * * @param {String|Array} [events] list of commands to register on * @param {String} [hook] command hook, i.e. preExecute, executed to listen on * @param {Number} [priority] the priority on which to hook into the execution * @param {Function} handlerFn interceptor to be invoked with (event) * @param {Boolean} unwrap if true, unwrap the event and pass (context, command, event) to the * listener instead * @param {Object} [that] Pass context (`this`) to the handler function */ CommandInterceptor.prototype.on = function (events, hook, priority, handlerFn, unwrap, that) { if ((0, _minDash.isFunction)(hook) || (0, _minDash.isNumber)(hook)) { that = unwrap; unwrap = handlerFn; handlerFn = priority; priority = hook; hook = null; } if ((0, _minDash.isFunction)(priority)) { that = unwrap; unwrap = handlerFn; handlerFn = priority; priority = DEFAULT_PRIORITY; } if ((0, _minDash.isObject)(unwrap)) { that = unwrap; unwrap = false; } if (!(0, _minDash.isFunction)(handlerFn)) { throw new Error('handlerFn must be a function'); } if (!(0, _minDash.isArray)(events)) { events = [events]; } var eventBus = this._eventBus; (0, _minDash.forEach)(events, function (event) { // concat commandStack(.event)?(.hook)? var fullEvent = ['commandStack', event, hook].filter(function (e) { return e; }).join('.'); eventBus.on(fullEvent, priority, unwrap ? unwrapEvent(handlerFn, that) : handlerFn, that); }); }; var hooks = ['canExecute', 'preExecute', 'preExecuted', 'execute', 'executed', 'postExecute', 'postExecuted', 'revert', 'reverted']; /* * Install hook shortcuts * * This will generate the CommandInterceptor#(preExecute|...|reverted) methods * which will in term forward to CommandInterceptor#on. */ (0, _minDash.forEach)(hooks, function (hook) { /** * {canExecute|preExecute|preExecuted|execute|executed|postExecute|postExecuted|revert|reverted} * * A named hook for plugging into the command execution * * @param {String|Array} [events] list of commands to register on * @param {Number} [priority] the priority on which to hook into the execution * @param {Function} handlerFn interceptor to be invoked with (event) * @param {Boolean} [unwrap=false] if true, unwrap the event and pass (context, command, event) to the * listener instead * @param {Object} [that] Pass context (`this`) to the handler function */ CommandInterceptor.prototype[hook] = function (events, priority, handlerFn, unwrap, that) { if ((0, _minDash.isFunction)(events) || (0, _minDash.isNumber)(events)) { that = unwrap; unwrap = handlerFn; handlerFn = priority; priority = events; events = null; } this.on(events, hook, priority, handlerFn, unwrap, that); }; }); },{"min-dash":505}],244:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CommandStack; var _minDash = require('min-dash'); /** * A service that offers un- and redoable execution of commands. * * The command stack is responsible for executing modeling actions * in a un- and redoable manner. To do this it delegates the actual * command execution to {@link CommandHandler}s. * * Command handlers provide {@link CommandHandler#execute(ctx)} and * {@link CommandHandler#revert(ctx)} methods to un- and redo a command * identified by a command context. * * * ## Life-Cycle events * * In the process the command stack fires a number of life-cycle events * that other components to participate in the command execution. * * * preExecute * * preExecuted * * execute * * executed * * postExecute * * postExecuted * * revert * * reverted * * A special event is used for validating, whether a command can be * performed prior to its execution. * * * canExecute * * Each of the events is fired as `commandStack.{eventName}` and * `commandStack.{commandName}.{eventName}`, respectively. This gives * components fine grained control on where to hook into. * * The event object fired transports `command`, the name of the * command and `context`, the command context. * * * ## Creating Command Handlers * * Command handlers should provide the {@link CommandHandler#execute(ctx)} * and {@link CommandHandler#revert(ctx)} methods to implement * redoing and undoing of a command. * * A command handler _must_ ensure undo is performed properly in order * not to break the undo chain. It must also return the shapes that * got changed during the `execute` and `revert` operations. * * Command handlers may execute other modeling operations (and thus * commands) in their `preExecute` and `postExecute` phases. The command * stack will properly group all commands together into a logical unit * that may be re- and undone atomically. * * Command handlers must not execute other commands from within their * core implementation (`execute`, `revert`). * * * ## Change Tracking * * During the execution of the CommandStack it will keep track of all * elements that have been touched during the command's execution. * * At the end of the CommandStack execution it will notify interested * components via an 'elements.changed' event with all the dirty * elements. * * The event can be picked up by components that are interested in the fact * that elements have been changed. One use case for this is updating * their graphical representation after moving / resizing or deletion. * * @see CommandHandler * * @param {EventBus} eventBus * @param {Injector} injector */ function CommandStack(eventBus, injector) { /** * A map of all registered command handlers. * * @type {Object} */ this._handlerMap = {}; /** * A stack containing all re/undoable actions on the diagram * * @type {Array} */ this._stack = []; /** * The current index on the stack * * @type {Number} */ this._stackIdx = -1; /** * Current active commandStack execution * * @type {Object} */ this._currentExecution = { actions: [], dirty: [] }; this._injector = injector; this._eventBus = eventBus; this._uid = 1; eventBus.on(['diagram.destroy', 'diagram.clear'], function () { this.clear(false); }, this); } CommandStack.$inject = ['eventBus', 'injector']; /** * Execute a command * * @param {String} command the command to execute * @param {Object} context the environment to execute the command in */ CommandStack.prototype.execute = function (command, context) { if (!command) { throw new Error('command required'); } var action = { command: command, context: context }; this._pushAction(action); this._internalExecute(action); this._popAction(action); }; /** * Ask whether a given command can be executed. * * Implementors may hook into the mechanism on two ways: * * * in event listeners: * * Users may prevent the execution via an event listener. * It must prevent the default action for `commandStack.(.)canExecute` events. * * * in command handlers: * * If the method {@link CommandHandler#canExecute} is implemented in a handler * it will be called to figure out whether the execution is allowed. * * @param {String} command the command to execute * @param {Object} context the environment to execute the command in * * @return {Boolean} true if the command can be executed */ CommandStack.prototype.canExecute = function (command, context) { var action = { command: command, context: context }; var handler = this._getHandler(command); var result = this._fire(command, 'canExecute', action); // handler#canExecute will only be called if no listener // decided on a result already if (result === undefined) { if (!handler) { return false; } if (handler.canExecute) { result = handler.canExecute(context); } } return result; }; /** * Clear the command stack, erasing all undo / redo history */ CommandStack.prototype.clear = function (emit) { this._stack.length = 0; this._stackIdx = -1; if (emit !== false) { this._fire('changed'); } }; /** * Undo last command(s) */ CommandStack.prototype.undo = function () { var action = this._getUndoAction(), next; if (action) { this._pushAction(action); while (action) { this._internalUndo(action); next = this._getUndoAction(); if (!next || next.id !== action.id) { break; } action = next; } this._popAction(); } }; /** * Redo last command(s) */ CommandStack.prototype.redo = function () { var action = this._getRedoAction(), next; if (action) { this._pushAction(action); while (action) { this._internalExecute(action, true); next = this._getRedoAction(); if (!next || next.id !== action.id) { break; } action = next; } this._popAction(); } }; /** * Register a handler instance with the command stack * * @param {String} command * @param {CommandHandler} handler */ CommandStack.prototype.register = function (command, handler) { this._setHandler(command, handler); }; /** * Register a handler type with the command stack * by instantiating it and injecting its dependencies. * * @param {String} command * @param {Function} a constructor for a {@link CommandHandler} */ CommandStack.prototype.registerHandler = function (command, handlerCls) { if (!command || !handlerCls) { throw new Error('command and handlerCls must be defined'); } var handler = this._injector.instantiate(handlerCls); this.register(command, handler); }; CommandStack.prototype.canUndo = function () { return !!this._getUndoAction(); }; CommandStack.prototype.canRedo = function () { return !!this._getRedoAction(); }; // stack access ////////////////////// CommandStack.prototype._getRedoAction = function () { return this._stack[this._stackIdx + 1]; }; CommandStack.prototype._getUndoAction = function () { return this._stack[this._stackIdx]; }; // internal functionality ////////////////////// CommandStack.prototype._internalUndo = function (action) { var self = this; var command = action.command, context = action.context; var handler = this._getHandler(command); // guard against illegal nested command stack invocations this._atomicDo(function () { self._fire(command, 'revert', action); if (handler.revert) { self._markDirty(handler.revert(context)); } self._revertedAction(action); self._fire(command, 'reverted', action); }); }; CommandStack.prototype._fire = function (command, qualifier, event) { if (arguments.length < 3) { event = qualifier; qualifier = null; } var names = qualifier ? [command + '.' + qualifier, qualifier] : [command], i, name, result; event = this._eventBus.createEvent(event); for (i = 0; name = names[i]; i++) { result = this._eventBus.fire('commandStack.' + name, event); if (event.cancelBubble) { break; } } return result; }; CommandStack.prototype._createId = function () { return this._uid++; }; CommandStack.prototype._atomicDo = function (fn) { var execution = this._currentExecution; execution.atomic = true; try { fn(); } finally { execution.atomic = false; } }; CommandStack.prototype._internalExecute = function (action, redo) { var self = this; var command = action.command, context = action.context; var handler = this._getHandler(command); if (!handler) { throw new Error('no command handler registered for <' + command + '>'); } this._pushAction(action); if (!redo) { this._fire(command, 'preExecute', action); if (handler.preExecute) { handler.preExecute(context); } this._fire(command, 'preExecuted', action); } // guard against illegal nested command stack invocations this._atomicDo(function () { self._fire(command, 'execute', action); if (handler.execute) { // actual execute + mark return results as dirty self._markDirty(handler.execute(context)); } // log to stack self._executedAction(action, redo); self._fire(command, 'executed', action); }); if (!redo) { this._fire(command, 'postExecute', action); if (handler.postExecute) { handler.postExecute(context); } this._fire(command, 'postExecuted', action); } this._popAction(action); }; CommandStack.prototype._pushAction = function (action) { var execution = this._currentExecution, actions = execution.actions; var baseAction = actions[0]; if (execution.atomic) { throw new Error('illegal invocation in or phase (action: ' + action.command + ')'); } if (!action.id) { action.id = baseAction && baseAction.id || this._createId(); } actions.push(action); }; CommandStack.prototype._popAction = function () { var execution = this._currentExecution, actions = execution.actions, dirty = execution.dirty; actions.pop(); if (!actions.length) { this._eventBus.fire('elements.changed', { elements: (0, _minDash.uniqueBy)('id', dirty) }); dirty.length = 0; this._fire('changed'); } }; CommandStack.prototype._markDirty = function (elements) { var execution = this._currentExecution; if (!elements) { return; } elements = (0, _minDash.isArray)(elements) ? elements : [elements]; execution.dirty = execution.dirty.concat(elements); }; CommandStack.prototype._executedAction = function (action, redo) { var stackIdx = ++this._stackIdx; if (!redo) { this._stack.splice(stackIdx, this._stack.length, action); } }; CommandStack.prototype._revertedAction = function (action) { this._stackIdx--; }; CommandStack.prototype._getHandler = function (command) { return this._handlerMap[command]; }; CommandStack.prototype._setHandler = function (command, handler) { if (!command || !handler) { throw new Error('command and handler required'); } if (this._handlerMap[command]) { throw new Error('overriding handler for command <' + command + '>'); } this._handlerMap[command] = handler; }; },{"min-dash":505}],245:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _CommandStack = require('./CommandStack'); var _CommandStack2 = _interopRequireDefault(_CommandStack); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { commandStack: ['type', _CommandStack2.default] }; },{"./CommandStack":244}],246:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; exports.default = Canvas; var _minDash = require('min-dash'); var _Collections = require('../util/Collections'); var _Elements = require('../util/Elements'); var _tinySvg = require('tiny-svg'); function round(number, resolution) { return Math.round(number * resolution) / resolution; } function ensurePx(number) { return (0, _minDash.isNumber)(number) ? number + 'px' : number; } /** * Creates a HTML container element for a SVG element with * the given configuration * * @param {Object} options * @return {HTMLElement} the container element */ function createContainer(options) { options = (0, _minDash.assign)({}, { width: '100%', height: '100%' }, options); var container = options.container || document.body; // create a
around the svg element with the respective size // this way we can always get the correct container size // (this is impossible for elements at the moment) var parent = document.createElement('div'); parent.setAttribute('class', 'djs-container'); (0, _minDash.assign)(parent.style, { position: 'relative', overflow: 'hidden', width: ensurePx(options.width), height: ensurePx(options.height) }); container.appendChild(parent); return parent; } function createGroup(parent, cls, childIndex) { var group = (0, _tinySvg.create)('g'); (0, _tinySvg.classes)(group).add(cls); var index = childIndex !== undefined ? childIndex : parent.childNodes.length - 1; // must ensure second argument is node or _null_ // cf. https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore parent.insertBefore(group, parent.childNodes[index] || null); return group; } var BASE_LAYER = 'base'; var REQUIRED_MODEL_ATTRS = { shape: ['x', 'y', 'width', 'height'], connection: ['waypoints'] }; /** * The main drawing canvas. * * @class * @constructor * * @emits Canvas#canvas.init * * @param {Object} config * @param {EventBus} eventBus * @param {GraphicsFactory} graphicsFactory * @param {ElementRegistry} elementRegistry */ function Canvas(config, eventBus, graphicsFactory, elementRegistry) { this._eventBus = eventBus; this._elementRegistry = elementRegistry; this._graphicsFactory = graphicsFactory; this._init(config || {}); } Canvas.$inject = ['config.canvas', 'eventBus', 'graphicsFactory', 'elementRegistry']; Canvas.prototype._init = function (config) { var eventBus = this._eventBus; // Creates a element that is wrapped into a
. // This way we are always able to correctly figure out the size of the svg element // by querying the parent node. // // (It is not possible to get the size of a svg element cross browser @ 2014-04-01) // //
// // ... // //
// html container var container = this._container = createContainer(config); var svg = this._svg = (0, _tinySvg.create)('svg'); (0, _tinySvg.attr)(svg, { width: '100%', height: '100%' }); (0, _tinySvg.append)(container, svg); var viewport = this._viewport = createGroup(svg, 'viewport'); this._layers = {}; // debounce canvas.viewbox.changed events // for smoother diagram interaction if (config.deferUpdate !== false) { this._viewboxChanged = (0, _minDash.debounce)((0, _minDash.bind)(this._viewboxChanged, this), 300); } eventBus.on('diagram.init', function () { /** * An event indicating that the canvas is ready to be drawn on. * * @memberOf Canvas * * @event canvas.init * * @type {Object} * @property {SVGElement} svg the created svg element * @property {SVGElement} viewport the direct parent of diagram elements and shapes */ eventBus.fire('canvas.init', { svg: svg, viewport: viewport }); }, this); // reset viewbox on shape changes to // recompute the viewbox eventBus.on(['shape.added', 'connection.added', 'shape.removed', 'connection.removed', 'elements.changed'], function () { delete this._cachedViewbox; }, this); eventBus.on('diagram.destroy', 500, this._destroy, this); eventBus.on('diagram.clear', 500, this._clear, this); }; Canvas.prototype._destroy = function (emit) { this._eventBus.fire('canvas.destroy', { svg: this._svg, viewport: this._viewport }); var parent = this._container.parentNode; if (parent) { parent.removeChild(this._container); } delete this._svg; delete this._container; delete this._layers; delete this._rootElement; delete this._viewport; }; Canvas.prototype._clear = function () { var self = this; var allElements = this._elementRegistry.getAll(); // remove all elements allElements.forEach(function (element) { var type = (0, _Elements.getType)(element); if (type === 'root') { self.setRootElement(null, true); } else { self._removeElement(element, type); } }); // force recomputation of view box delete this._cachedViewbox; }; /** * Returns the default layer on which * all elements are drawn. * * @returns {SVGElement} */ Canvas.prototype.getDefaultLayer = function () { return this.getLayer(BASE_LAYER, 0); }; /** * Returns a layer that is used to draw elements * or annotations on it. * * Non-existing layers retrieved through this method * will be created. During creation, the optional index * may be used to create layers below or above existing layers. * A layer with a certain index is always created above all * existing layers with the same index. * * @param {String} name * @param {Number} index * * @returns {SVGElement} */ Canvas.prototype.getLayer = function (name, index) { if (!name) { throw new Error('must specify a name'); } var layer = this._layers[name]; if (!layer) { layer = this._layers[name] = this._createLayer(name, index); } // throw an error if layer creation / retrival is // requested on different index if (typeof index !== 'undefined' && layer.index !== index) { throw new Error('layer <' + name + '> already created at index <' + index + '>'); } return layer.group; }; /** * Creates a given layer and returns it. * * @param {String} name * @param {Number} [index=0] * * @return {Object} layer descriptor with { index, group: SVGGroup } */ Canvas.prototype._createLayer = function (name, index) { if (!index) { index = 0; } var childIndex = (0, _minDash.reduce)(this._layers, function (childIndex, layer) { if (index >= layer.index) { childIndex++; } return childIndex; }, 0); return { group: createGroup(this._viewport, 'layer-' + name, childIndex), index: index }; }; /** * Returns the html element that encloses the * drawing canvas. * * @return {DOMNode} */ Canvas.prototype.getContainer = function () { return this._container; }; // markers ////////////////////// Canvas.prototype._updateMarker = function (element, marker, add) { var container; if (!element.id) { element = this._elementRegistry.get(element); } // we need to access all container = this._elementRegistry._elements[element.id]; if (!container) { return; } (0, _minDash.forEach)([container.gfx, container.secondaryGfx], function (gfx) { if (gfx) { // invoke either addClass or removeClass based on mode if (add) { (0, _tinySvg.classes)(gfx).add(marker); } else { (0, _tinySvg.classes)(gfx).remove(marker); } } }); /** * An event indicating that a marker has been updated for an element * * @event element.marker.update * @type {Object} * @property {djs.model.Element} element the shape * @property {Object} gfx the graphical representation of the shape * @property {String} marker * @property {Boolean} add true if the marker was added, false if it got removed */ this._eventBus.fire('element.marker.update', { element: element, gfx: container.gfx, marker: marker, add: !!add }); }; /** * Adds a marker to an element (basically a css class). * * Fires the element.marker.update event, making it possible to * integrate extension into the marker life-cycle, too. * * @example * canvas.addMarker('foo', 'some-marker'); * * var fooGfx = canvas.getGraphics('foo'); * * fooGfx; // ... * * @param {String|djs.model.Base} element * @param {String} marker */ Canvas.prototype.addMarker = function (element, marker) { this._updateMarker(element, marker, true); }; /** * Remove a marker from an element. * * Fires the element.marker.update event, making it possible to * integrate extension into the marker life-cycle, too. * * @param {String|djs.model.Base} element * @param {String} marker */ Canvas.prototype.removeMarker = function (element, marker) { this._updateMarker(element, marker, false); }; /** * Check the existence of a marker on element. * * @param {String|djs.model.Base} element * @param {String} marker */ Canvas.prototype.hasMarker = function (element, marker) { if (!element.id) { element = this._elementRegistry.get(element); } var gfx = this.getGraphics(element); return (0, _tinySvg.classes)(gfx).has(marker); }; /** * Toggles a marker on an element. * * Fires the element.marker.update event, making it possible to * integrate extension into the marker life-cycle, too. * * @param {String|djs.model.Base} element * @param {String} marker */ Canvas.prototype.toggleMarker = function (element, marker) { if (this.hasMarker(element, marker)) { this.removeMarker(element, marker); } else { this.addMarker(element, marker); } }; Canvas.prototype.getRootElement = function () { if (!this._rootElement) { this.setRootElement({ id: '__implicitroot', children: [] }); } return this._rootElement; }; // root element handling ////////////////////// /** * Sets a given element as the new root element for the canvas * and returns the new root element. * * @param {Object|djs.model.Root} element * @param {Boolean} [override] whether to override the current root element, if any * * @return {Object|djs.model.Root} new root element */ Canvas.prototype.setRootElement = function (element, override) { if (element) { this._ensureValid('root', element); } var currentRoot = this._rootElement, elementRegistry = this._elementRegistry, eventBus = this._eventBus; if (currentRoot) { if (!override) { throw new Error('rootElement already set, need to specify override'); } // simulate element remove event sequence eventBus.fire('root.remove', { element: currentRoot }); eventBus.fire('root.removed', { element: currentRoot }); elementRegistry.remove(currentRoot); } if (element) { var gfx = this.getDefaultLayer(); // resemble element add event sequence eventBus.fire('root.add', { element: element }); elementRegistry.add(element, gfx, this._svg); eventBus.fire('root.added', { element: element, gfx: gfx }); } this._rootElement = element; return element; }; // add functionality ////////////////////// Canvas.prototype._ensureValid = function (type, element) { if (!element.id) { throw new Error('element must have an id'); } if (this._elementRegistry.get(element.id)) { throw new Error('element with id ' + element.id + ' already exists'); } var requiredAttrs = REQUIRED_MODEL_ATTRS[type]; var valid = (0, _minDash.every)(requiredAttrs, function (attr) { return typeof element[attr] !== 'undefined'; }); if (!valid) { throw new Error('must supply { ' + requiredAttrs.join(', ') + ' } with ' + type); } }; Canvas.prototype._setParent = function (element, parent, parentIndex) { (0, _Collections.add)(parent.children, element, parentIndex); element.parent = parent; }; /** * Adds an element to the canvas. * * This wires the parent <-> child relationship between the element and * a explicitly specified parent or an implicit root element. * * During add it emits the events * * * <{type}.add> (element, parent) * * <{type}.added> (element, gfx) * * Extensions may hook into these events to perform their magic. * * @param {String} type * @param {Object|djs.model.Base} element * @param {Object|djs.model.Base} [parent] * @param {Number} [parentIndex] * * @return {Object|djs.model.Base} the added element */ Canvas.prototype._addElement = function (type, element, parent, parentIndex) { parent = parent || this.getRootElement(); var eventBus = this._eventBus, graphicsFactory = this._graphicsFactory; this._ensureValid(type, element); eventBus.fire(type + '.add', { element: element, parent: parent }); this._setParent(element, parent, parentIndex); // create graphics var gfx = graphicsFactory.create(type, element, parentIndex); this._elementRegistry.add(element, gfx); // update its visual graphicsFactory.update(type, element, gfx); eventBus.fire(type + '.added', { element: element, gfx: gfx }); return element; }; /** * Adds a shape to the canvas * * @param {Object|djs.model.Shape} shape to add to the diagram * @param {djs.model.Base} [parent] * @param {Number} [parentIndex] * * @return {djs.model.Shape} the added shape */ Canvas.prototype.addShape = function (shape, parent, parentIndex) { return this._addElement('shape', shape, parent, parentIndex); }; /** * Adds a connection to the canvas * * @param {Object|djs.model.Connection} connection to add to the diagram * @param {djs.model.Base} [parent] * @param {Number} [parentIndex] * * @return {djs.model.Connection} the added connection */ Canvas.prototype.addConnection = function (connection, parent, parentIndex) { return this._addElement('connection', connection, parent, parentIndex); }; /** * Internal remove element */ Canvas.prototype._removeElement = function (element, type) { var elementRegistry = this._elementRegistry, graphicsFactory = this._graphicsFactory, eventBus = this._eventBus; element = elementRegistry.get(element.id || element); if (!element) { // element was removed already return; } eventBus.fire(type + '.remove', { element: element }); graphicsFactory.remove(element); // unset parent <-> child relationship (0, _Collections.remove)(element.parent && element.parent.children, element); element.parent = null; eventBus.fire(type + '.removed', { element: element }); elementRegistry.remove(element); return element; }; /** * Removes a shape from the canvas * * @param {String|djs.model.Shape} shape or shape id to be removed * * @return {djs.model.Shape} the removed shape */ Canvas.prototype.removeShape = function (shape) { /** * An event indicating that a shape is about to be removed from the canvas. * * @memberOf Canvas * * @event shape.remove * @type {Object} * @property {djs.model.Shape} element the shape descriptor * @property {Object} gfx the graphical representation of the shape */ /** * An event indicating that a shape has been removed from the canvas. * * @memberOf Canvas * * @event shape.removed * @type {Object} * @property {djs.model.Shape} element the shape descriptor * @property {Object} gfx the graphical representation of the shape */ return this._removeElement(shape, 'shape'); }; /** * Removes a connection from the canvas * * @param {String|djs.model.Connection} connection or connection id to be removed * * @return {djs.model.Connection} the removed connection */ Canvas.prototype.removeConnection = function (connection) { /** * An event indicating that a connection is about to be removed from the canvas. * * @memberOf Canvas * * @event connection.remove * @type {Object} * @property {djs.model.Connection} element the connection descriptor * @property {Object} gfx the graphical representation of the connection */ /** * An event indicating that a connection has been removed from the canvas. * * @memberOf Canvas * * @event connection.removed * @type {Object} * @property {djs.model.Connection} element the connection descriptor * @property {Object} gfx the graphical representation of the connection */ return this._removeElement(connection, 'connection'); }; /** * Return the graphical object underlaying a certain diagram element * * @param {String|djs.model.Base} element descriptor of the element * @param {Boolean} [secondary=false] whether to return the secondary connected element * * @return {SVGElement} */ Canvas.prototype.getGraphics = function (element, secondary) { return this._elementRegistry.getGraphics(element, secondary); }; /** * Perform a viewbox update via a given change function. * * @param {Function} changeFn */ Canvas.prototype._changeViewbox = function (changeFn) { // notify others of the upcoming viewbox change this._eventBus.fire('canvas.viewbox.changing'); // perform actual change changeFn.apply(this); // reset the cached viewbox so that // a new get operation on viewbox or zoom // triggers a viewbox re-computation this._cachedViewbox = null; // notify others of the change; this step // may or may not be debounced this._viewboxChanged(); }; Canvas.prototype._viewboxChanged = function () { this._eventBus.fire('canvas.viewbox.changed', { viewbox: this.viewbox() }); }; /** * Gets or sets the view box of the canvas, i.e. the * area that is currently displayed. * * The getter may return a cached viewbox (if it is currently * changing). To force a recomputation, pass `false` as the first argument. * * @example * * canvas.viewbox({ x: 100, y: 100, width: 500, height: 500 }) * * // sets the visible area of the diagram to (100|100) -> (600|100) * // and and scales it according to the diagram width * * var viewbox = canvas.viewbox(); // pass `false` to force recomputing the box. * * console.log(viewbox); * // { * // inner: Dimensions, * // outer: Dimensions, * // scale, * // x, y, * // width, height * // } * * // if the current diagram is zoomed and scrolled, you may reset it to the * // default zoom via this method, too: * * var zoomedAndScrolledViewbox = canvas.viewbox(); * * canvas.viewbox({ * x: 0, * y: 0, * width: zoomedAndScrolledViewbox.outer.width, * height: zoomedAndScrolledViewbox.outer.height * }); * * @param {Object} [box] the new view box to set * @param {Number} box.x the top left X coordinate of the canvas visible in view box * @param {Number} box.y the top left Y coordinate of the canvas visible in view box * @param {Number} box.width the visible width * @param {Number} box.height * * @return {Object} the current view box */ Canvas.prototype.viewbox = function (box) { if (box === undefined && this._cachedViewbox) { return this._cachedViewbox; } var viewport = this._viewport, innerBox, outerBox = this.getSize(), matrix, transform, scale, x, y; if (!box) { // compute the inner box based on the // diagrams default layer. This allows us to exclude // external components, such as overlays innerBox = this.getDefaultLayer().getBBox(); transform = (0, _tinySvg.transform)(viewport); matrix = transform ? transform.matrix : (0, _tinySvg.createMatrix)(); scale = round(matrix.a, 1000); x = round(-matrix.e || 0, 1000); y = round(-matrix.f || 0, 1000); box = this._cachedViewbox = { x: x ? x / scale : 0, y: y ? y / scale : 0, width: outerBox.width / scale, height: outerBox.height / scale, scale: scale, inner: { width: innerBox.width, height: innerBox.height, x: innerBox.x, y: innerBox.y }, outer: outerBox }; return box; } else { this._changeViewbox(function () { scale = Math.min(outerBox.width / box.width, outerBox.height / box.height); var matrix = this._svg.createSVGMatrix().scale(scale).translate(-box.x, -box.y); (0, _tinySvg.transform)(viewport, matrix); }); } return box; }; /** * Gets or sets the scroll of the canvas. * * @param {Object} [delta] the new scroll to apply. * * @param {Number} [delta.dx] * @param {Number} [delta.dy] */ Canvas.prototype.scroll = function (delta) { var node = this._viewport; var matrix = node.getCTM(); if (delta) { this._changeViewbox(function () { delta = (0, _minDash.assign)({ dx: 0, dy: 0 }, delta || {}); matrix = this._svg.createSVGMatrix().translate(delta.dx, delta.dy).multiply(matrix); setCTM(node, matrix); }); } return { x: matrix.e, y: matrix.f }; }; /** * Gets or sets the current zoom of the canvas, optionally zooming * to the specified position. * * The getter may return a cached zoom level. Call it with `false` as * the first argument to force recomputation of the current level. * * @param {String|Number} [newScale] the new zoom level, either a number, i.e. 0.9, * or `fit-viewport` to adjust the size to fit the current viewport * @param {String|Point} [center] the reference point { x: .., y: ..} to zoom to, 'auto' to zoom into mid or null * * @return {Number} the current scale */ Canvas.prototype.zoom = function (newScale, center) { if (!newScale) { return this.viewbox(newScale).scale; } if (newScale === 'fit-viewport') { return this._fitViewport(center); } var outer, matrix; this._changeViewbox(function () { if ((typeof center === 'undefined' ? 'undefined' : _typeof(center)) !== 'object') { outer = this.viewbox().outer; center = { x: outer.width / 2, y: outer.height / 2 }; } matrix = this._setZoom(newScale, center); }); return round(matrix.a, 1000); }; function setCTM(node, m) { var mstr = 'matrix(' + m.a + ',' + m.b + ',' + m.c + ',' + m.d + ',' + m.e + ',' + m.f + ')'; node.setAttribute('transform', mstr); } Canvas.prototype._fitViewport = function (center) { var vbox = this.viewbox(), outer = vbox.outer, inner = vbox.inner, newScale, newViewbox; // display the complete diagram without zooming in. // instead of relying on internal zoom, we perform a // hard reset on the canvas viewbox to realize this // // if diagram does not need to be zoomed in, we focus it around // the diagram origin instead if (inner.x >= 0 && inner.y >= 0 && inner.x + inner.width <= outer.width && inner.y + inner.height <= outer.height && !center) { newViewbox = { x: 0, y: 0, width: Math.max(inner.width + inner.x, outer.width), height: Math.max(inner.height + inner.y, outer.height) }; } else { newScale = Math.min(1, outer.width / inner.width, outer.height / inner.height); newViewbox = { x: inner.x + (center ? inner.width / 2 - outer.width / newScale / 2 : 0), y: inner.y + (center ? inner.height / 2 - outer.height / newScale / 2 : 0), width: outer.width / newScale, height: outer.height / newScale }; } this.viewbox(newViewbox); return this.viewbox(false).scale; }; Canvas.prototype._setZoom = function (scale, center) { var svg = this._svg, viewport = this._viewport; var matrix = svg.createSVGMatrix(); var point = svg.createSVGPoint(); var centerPoint, originalPoint, currentMatrix, scaleMatrix, newMatrix; currentMatrix = viewport.getCTM(); var currentScale = currentMatrix.a; if (center) { centerPoint = (0, _minDash.assign)(point, center); // revert applied viewport transformations originalPoint = centerPoint.matrixTransform(currentMatrix.inverse()); // create scale matrix scaleMatrix = matrix.translate(originalPoint.x, originalPoint.y).scale(1 / currentScale * scale).translate(-originalPoint.x, -originalPoint.y); newMatrix = currentMatrix.multiply(scaleMatrix); } else { newMatrix = matrix.scale(scale); } setCTM(this._viewport, newMatrix); return newMatrix; }; /** * Returns the size of the canvas * * @return {Dimensions} */ Canvas.prototype.getSize = function () { return { width: this._container.clientWidth, height: this._container.clientHeight }; }; /** * Return the absolute bounding box for the given element * * The absolute bounding box may be used to display overlays in the * callers (browser) coordinate system rather than the zoomed in/out * canvas coordinates. * * @param {ElementDescriptor} element * @return {Bounds} the absolute bounding box */ Canvas.prototype.getAbsoluteBBox = function (element) { var vbox = this.viewbox(); var bbox; // connection // use svg bbox if (element.waypoints) { var gfx = this.getGraphics(element); bbox = gfx.getBBox(); } // shapes // use data else { bbox = element; } var x = bbox.x * vbox.scale - vbox.x * vbox.scale; var y = bbox.y * vbox.scale - vbox.y * vbox.scale; var width = bbox.width * vbox.scale; var height = bbox.height * vbox.scale; return { x: x, y: y, width: width, height: height }; }; /** * Fires an event in order other modules can react to the * canvas resizing */ Canvas.prototype.resized = function () { // force recomputation of view box delete this._cachedViewbox; this._eventBus.fire('canvas.resized'); }; },{"../util/Collections":393,"../util/Elements":396,"min-dash":505,"tiny-svg":535}],247:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ElementFactory; var _model = require('../model'); var _minDash = require('min-dash'); /** * A factory for diagram-js shapes */ function ElementFactory() { this._uid = 12; } ElementFactory.prototype.createRoot = function (attrs) { return this.create('root', attrs); }; ElementFactory.prototype.createLabel = function (attrs) { return this.create('label', attrs); }; ElementFactory.prototype.createShape = function (attrs) { return this.create('shape', attrs); }; ElementFactory.prototype.createConnection = function (attrs) { return this.create('connection', attrs); }; /** * Create a model element with the given type and * a number of pre-set attributes. * * @param {String} type * @param {Object} attrs * @return {djs.model.Base} the newly created model instance */ ElementFactory.prototype.create = function (type, attrs) { attrs = (0, _minDash.assign)({}, attrs || {}); if (!attrs.id) { attrs.id = type + '_' + this._uid++; } return (0, _model.create)(type, attrs); }; },{"../model":382,"min-dash":505}],248:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ElementRegistry; var _tinySvg = require('tiny-svg'); var ELEMENT_ID = 'data-element-id'; /** * @class * * A registry that keeps track of all shapes in the diagram. */ function ElementRegistry(eventBus) { this._elements = {}; this._eventBus = eventBus; } ElementRegistry.$inject = ['eventBus']; /** * Register a pair of (element, gfx, (secondaryGfx)). * * @param {djs.model.Base} element * @param {SVGElement} gfx * @param {SVGElement} [secondaryGfx] optional other element to register, too */ ElementRegistry.prototype.add = function (element, gfx, secondaryGfx) { var id = element.id; this._validateId(id); // associate dom node with element (0, _tinySvg.attr)(gfx, ELEMENT_ID, id); if (secondaryGfx) { (0, _tinySvg.attr)(secondaryGfx, ELEMENT_ID, id); } this._elements[id] = { element: element, gfx: gfx, secondaryGfx: secondaryGfx }; }; /** * Removes an element from the registry. * * @param {djs.model.Base} element */ ElementRegistry.prototype.remove = function (element) { var elements = this._elements, id = element.id || element, container = id && elements[id]; if (container) { // unset element id on gfx (0, _tinySvg.attr)(container.gfx, ELEMENT_ID, ''); if (container.secondaryGfx) { (0, _tinySvg.attr)(container.secondaryGfx, ELEMENT_ID, ''); } delete elements[id]; } }; /** * Update the id of an element * * @param {djs.model.Base} element * @param {String} newId */ ElementRegistry.prototype.updateId = function (element, newId) { this._validateId(newId); if (typeof element === 'string') { element = this.get(element); } this._eventBus.fire('element.updateId', { element: element, newId: newId }); var gfx = this.getGraphics(element), secondaryGfx = this.getGraphics(element, true); this.remove(element); element.id = newId; this.add(element, gfx, secondaryGfx); }; /** * Return the model element for a given id or graphics. * * @example * * elementRegistry.get('SomeElementId_1'); * elementRegistry.get(gfx); * * * @param {String|SVGElement} filter for selecting the element * * @return {djs.model.Base} */ ElementRegistry.prototype.get = function (filter) { var id; if (typeof filter === 'string') { id = filter; } else { id = filter && (0, _tinySvg.attr)(filter, ELEMENT_ID); } var container = this._elements[id]; return container && container.element; }; /** * Return all elements that match a given filter function. * * @param {Function} fn * * @return {Array} */ ElementRegistry.prototype.filter = function (fn) { var filtered = []; this.forEach(function (element, gfx) { if (fn(element, gfx)) { filtered.push(element); } }); return filtered; }; /** * Return all rendered model elements. * * @return {Array} */ ElementRegistry.prototype.getAll = function () { return this.filter(function (e) { return e; }); }; /** * Iterate over all diagram elements. * * @param {Function} fn */ ElementRegistry.prototype.forEach = function (fn) { var map = this._elements; Object.keys(map).forEach(function (id) { var container = map[id], element = container.element, gfx = container.gfx; return fn(element, gfx); }); }; /** * Return the graphical representation of an element or its id. * * @example * elementRegistry.getGraphics('SomeElementId_1'); * elementRegistry.getGraphics(rootElement); // * * elementRegistry.getGraphics(rootElement, true); // * * * @param {String|djs.model.Base} filter * @param {Boolean} [secondary=false] whether to return the secondary connected element * * @return {SVGElement} */ ElementRegistry.prototype.getGraphics = function (filter, secondary) { var id = filter.id || filter; var container = this._elements[id]; return container && (secondary ? container.secondaryGfx : container.gfx); }; /** * Validate the suitability of the given id and signals a problem * with an exception. * * @param {String} id * * @throws {Error} if id is empty or already assigned */ ElementRegistry.prototype._validateId = function (id) { if (!id) { throw new Error('element must have an id'); } if (this._elements[id]) { throw new Error('element with id ' + id + ' already added'); } }; },{"tiny-svg":535}],249:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; exports.default = EventBus; var _minDash = require('min-dash'); var FN_REF = '__fn'; var DEFAULT_PRIORITY = 1000; var slice = Array.prototype.slice; /** * A general purpose event bus. * * This component is used to communicate across a diagram instance. * Other parts of a diagram can use it to listen to and broadcast events. * * * ## Registering for Events * * The event bus provides the {@link EventBus#on} and {@link EventBus#once} * methods to register for events. {@link EventBus#off} can be used to * remove event registrations. Listeners receive an instance of {@link Event} * as the first argument. It allows them to hook into the event execution. * * ```javascript * * // listen for event * eventBus.on('foo', function(event) { * * // access event type * event.type; // 'foo' * * // stop propagation to other listeners * event.stopPropagation(); * * // prevent event default * event.preventDefault(); * }); * * // listen for event with custom payload * eventBus.on('bar', function(event, payload) { * console.log(payload); * }); * * // listen for event returning value * eventBus.on('foobar', function(event) { * * // stop event propagation + prevent default * return false; * * // stop event propagation + return custom result * return { * complex: 'listening result' * }; * }); * * * // listen with custom priority (default=1000, higher is better) * eventBus.on('priorityfoo', 1500, function(event) { * console.log('invoked first!'); * }); * * * // listen for event and pass the context (`this`) * eventBus.on('foobar', function(event) { * this.foo(); * }, this); * ``` * * * ## Emitting Events * * Events can be emitted via the event bus using {@link EventBus#fire}. * * ```javascript * * // false indicates that the default action * // was prevented by listeners * if (eventBus.fire('foo') === false) { * console.log('default has been prevented!'); * }; * * * // custom args + return value listener * eventBus.on('sum', function(event, a, b) { * return a + b; * }); * * // you can pass custom arguments + retrieve result values. * var sum = eventBus.fire('sum', 1, 2); * console.log(sum); // 3 * ``` */ function EventBus() { this._listeners = {}; // cleanup on destroy on lowest priority to allow // message passing until the bitter end this.on('diagram.destroy', 1, this._destroy, this); } /** * Register an event listener for events with the given name. * * The callback will be invoked with `event, ...additionalArguments` * that have been passed to {@link EventBus#fire}. * * Returning false from a listener will prevent the events default action * (if any is specified). To stop an event from being processed further in * other listeners execute {@link Event#stopPropagation}. * * Returning anything but `undefined` from a listener will stop the listener propagation. * * @param {String|Array} events * @param {Number} [priority=1000] the priority in which this listener is called, larger is higher * @param {Function} callback * @param {Object} [that] Pass context (`this`) to the callback */ EventBus.prototype.on = function (events, priority, callback, that) { events = (0, _minDash.isArray)(events) ? events : [events]; if ((0, _minDash.isFunction)(priority)) { that = callback; callback = priority; priority = DEFAULT_PRIORITY; } if (!(0, _minDash.isNumber)(priority)) { throw new Error('priority must be a number'); } var actualCallback = callback; if (that) { actualCallback = (0, _minDash.bind)(callback, that); // make sure we remember and are able to remove // bound callbacks via {@link #off} using the original // callback actualCallback[FN_REF] = callback[FN_REF] || callback; } var self = this; events.forEach(function (e) { self._addListener(e, { priority: priority, callback: actualCallback, next: null }); }); }; /** * Register an event listener that is executed only once. * * @param {String} event the event name to register for * @param {Function} callback the callback to execute * @param {Object} [that] Pass context (`this`) to the callback */ EventBus.prototype.once = function (event, priority, callback, that) { var self = this; if ((0, _minDash.isFunction)(priority)) { that = callback; callback = priority; priority = DEFAULT_PRIORITY; } if (!(0, _minDash.isNumber)(priority)) { throw new Error('priority must be a number'); } function wrappedCallback() { var result = callback.apply(that, arguments); self.off(event, wrappedCallback); return result; } // make sure we remember and are able to remove // bound callbacks via {@link #off} using the original // callback wrappedCallback[FN_REF] = callback; this.on(event, priority, wrappedCallback); }; /** * Removes event listeners by event and callback. * * If no callback is given, all listeners for a given event name are being removed. * * @param {String|Array} events * @param {Function} [callback] */ EventBus.prototype.off = function (events, callback) { events = (0, _minDash.isArray)(events) ? events : [events]; var self = this; events.forEach(function (event) { self._removeListener(event, callback); }); }; /** * Create an EventBus event. * * @param {Object} data * * @return {Object} event, recognized by the eventBus */ EventBus.prototype.createEvent = function (data) { var event = new InternalEvent(); event.init(data); return event; }; /** * Fires a named event. * * @example * * // fire event by name * events.fire('foo'); * * // fire event object with nested type * var event = { type: 'foo' }; * events.fire(event); * * // fire event with explicit type * var event = { x: 10, y: 20 }; * events.fire('element.moved', event); * * // pass additional arguments to the event * events.on('foo', function(event, bar) { * alert(bar); * }); * * events.fire({ type: 'foo' }, 'I am bar!'); * * @param {String} [name] the optional event name * @param {Object} [event] the event object * @param {...Object} additional arguments to be passed to the callback functions * * @return {Boolean} the events return value, if specified or false if the * default action was prevented by listeners */ EventBus.prototype.fire = function (type, data) { var event, firstListener, returnValue, args; args = slice.call(arguments); if ((typeof type === 'undefined' ? 'undefined' : _typeof(type)) === 'object') { event = type; type = event.type; } if (!type) { throw new Error('no event type specified'); } firstListener = this._listeners[type]; if (!firstListener) { return; } // we make sure we fire instances of our home made // events here. We wrap them only once, though if (data instanceof InternalEvent) { // we are fine, we alread have an event event = data; } else { event = this.createEvent(data); } // ensure we pass the event as the first parameter args[0] = event; // original event type (in case we delegate) var originalType = event.type; // update event type before delegation if (type !== originalType) { event.type = type; } try { returnValue = this._invokeListeners(event, args, firstListener); } finally { // reset event type after delegation if (type !== originalType) { event.type = originalType; } } // set the return value to false if the event default // got prevented and no other return value exists if (returnValue === undefined && event.defaultPrevented) { returnValue = false; } return returnValue; }; EventBus.prototype.handleError = function (error) { return this.fire('error', { error: error }) === false; }; EventBus.prototype._destroy = function () { this._listeners = {}; }; EventBus.prototype._invokeListeners = function (event, args, listener) { var returnValue; while (listener) { // handle stopped propagation if (event.cancelBubble) { break; } returnValue = this._invokeListener(event, args, listener); listener = listener.next; } return returnValue; }; EventBus.prototype._invokeListener = function (event, args, listener) { var returnValue; try { // returning false prevents the default action returnValue = invokeFunction(listener.callback, args); // stop propagation on return value if (returnValue !== undefined) { event.returnValue = returnValue; event.stopPropagation(); } // prevent default on return false if (returnValue === false) { event.preventDefault(); } } catch (e) { if (!this.handleError(e)) { console.error('unhandled error in event listener'); console.error(e.stack); throw e; } } return returnValue; }; /* * Add new listener with a certain priority to the list * of listeners (for the given event). * * The semantics of listener registration / listener execution are * first register, first serve: New listeners will always be inserted * after existing listeners with the same priority. * * Example: Inserting two listeners with priority 1000 and 1300 * * * before: [ 1500, 1500, 1000, 1000 ] * * after: [ 1500, 1500, (new=1300), 1000, 1000, (new=1000) ] * * @param {String} event * @param {Object} listener { priority, callback } */ EventBus.prototype._addListener = function (event, newListener) { var listener = this._getListeners(event), previousListener; // no prior listeners if (!listener) { this._setListeners(event, newListener); return; } // ensure we order listeners by priority from // 0 (high) to n > 0 (low) while (listener) { if (listener.priority < newListener.priority) { newListener.next = listener; if (previousListener) { previousListener.next = newListener; } else { this._setListeners(event, newListener); } return; } previousListener = listener; listener = listener.next; } // add new listener to back previousListener.next = newListener; }; EventBus.prototype._getListeners = function (name) { return this._listeners[name]; }; EventBus.prototype._setListeners = function (name, listener) { this._listeners[name] = listener; }; EventBus.prototype._removeListener = function (event, callback) { var listener = this._getListeners(event), nextListener, previousListener, listenerCallback; if (!callback) { // clear listeners this._setListeners(event, null); return; } while (listener) { nextListener = listener.next; listenerCallback = listener.callback; if (listenerCallback === callback || listenerCallback[FN_REF] === callback) { if (previousListener) { previousListener.next = nextListener; } else { // new first listener this._setListeners(event, nextListener); } } previousListener = listener; listener = nextListener; } }; /** * A event that is emitted via the event bus. */ function InternalEvent() {} InternalEvent.prototype.stopPropagation = function () { this.cancelBubble = true; }; InternalEvent.prototype.preventDefault = function () { this.defaultPrevented = true; }; InternalEvent.prototype.init = function (data) { (0, _minDash.assign)(this, data || {}); }; /** * Invoke function. Be fast... * * @param {Function} fn * @param {Array} args * * @return {Any} */ function invokeFunction(fn, args) { return fn.apply(null, args); } },{"min-dash":505}],250:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = GraphicsFactory; var _minDash = require('min-dash'); var _GraphicsUtil = require('../util/GraphicsUtil'); var _SvgTransformUtil = require('../util/SvgTransformUtil'); var _minDom = require('min-dom'); var _tinySvg = require('tiny-svg'); /** * A factory that creates graphical elements * * @param {EventBus} eventBus * @param {ElementRegistry} elementRegistry */ function GraphicsFactory(eventBus, elementRegistry) { this._eventBus = eventBus; this._elementRegistry = elementRegistry; } GraphicsFactory.$inject = ['eventBus', 'elementRegistry']; GraphicsFactory.prototype._getChildren = function (element) { var gfx = this._elementRegistry.getGraphics(element); var childrenGfx; // root element if (!element.parent) { childrenGfx = gfx; } else { childrenGfx = (0, _GraphicsUtil.getChildren)(gfx); if (!childrenGfx) { childrenGfx = (0, _tinySvg.create)('g'); (0, _tinySvg.classes)(childrenGfx).add('djs-children'); (0, _tinySvg.append)(gfx.parentNode, childrenGfx); } } return childrenGfx; }; /** * Clears the graphical representation of the element and returns the * cleared visual (the element). */ GraphicsFactory.prototype._clear = function (gfx) { var visual = (0, _GraphicsUtil.getVisual)(gfx); (0, _minDom.clear)(visual); return visual; }; /** * Creates a gfx container for shapes and connections * * The layout is as follows: * * * * * * * * * * * * * * @param {Object} parent * @param {String} type the type of the element, i.e. shape | connection * @param {Number} [parentIndex] position to create container in parent */ GraphicsFactory.prototype._createContainer = function (type, childrenGfx, parentIndex) { var outerGfx = (0, _tinySvg.create)('g'); (0, _tinySvg.classes)(outerGfx).add('djs-group'); // insert node at position if (typeof parentIndex !== 'undefined') { prependTo(outerGfx, childrenGfx, childrenGfx.childNodes[parentIndex]); } else { (0, _tinySvg.append)(childrenGfx, outerGfx); } var gfx = (0, _tinySvg.create)('g'); (0, _tinySvg.classes)(gfx).add('djs-element'); (0, _tinySvg.classes)(gfx).add('djs-' + type); (0, _tinySvg.append)(outerGfx, gfx); // create visual var visual = (0, _tinySvg.create)('g'); (0, _tinySvg.classes)(visual).add('djs-visual'); (0, _tinySvg.append)(gfx, visual); return gfx; }; GraphicsFactory.prototype.create = function (type, element, parentIndex) { var childrenGfx = this._getChildren(element.parent); return this._createContainer(type, childrenGfx, parentIndex); }; GraphicsFactory.prototype.updateContainments = function (elements) { var self = this, elementRegistry = this._elementRegistry, parents; parents = (0, _minDash.reduce)(elements, function (map, e) { if (e.parent) { map[e.parent.id] = e.parent; } return map; }, {}); // update all parents of changed and reorganized their children // in the correct order (as indicated in our model) (0, _minDash.forEach)(parents, function (parent) { var children = parent.children; if (!children) { return; } var childGfx = self._getChildren(parent); (0, _minDash.forEach)(children.slice().reverse(), function (c) { var gfx = elementRegistry.getGraphics(c); prependTo(gfx.parentNode, childGfx); }); }); }; GraphicsFactory.prototype.drawShape = function (visual, element) { var eventBus = this._eventBus; return eventBus.fire('render.shape', { gfx: visual, element: element }); }; GraphicsFactory.prototype.getShapePath = function (element) { var eventBus = this._eventBus; return eventBus.fire('render.getShapePath', element); }; GraphicsFactory.prototype.drawConnection = function (visual, element) { var eventBus = this._eventBus; return eventBus.fire('render.connection', { gfx: visual, element: element }); }; GraphicsFactory.prototype.getConnectionPath = function (waypoints) { var eventBus = this._eventBus; return eventBus.fire('render.getConnectionPath', waypoints); }; GraphicsFactory.prototype.update = function (type, element, gfx) { // Do not update root element if (!element.parent) { return; } var visual = this._clear(gfx); // redraw if (type === 'shape') { this.drawShape(visual, element); // update positioning (0, _SvgTransformUtil.translate)(gfx, element.x, element.y); } else if (type === 'connection') { this.drawConnection(visual, element); } else { throw new Error('unknown type: ' + type); } if (element.hidden) { (0, _tinySvg.attr)(gfx, 'display', 'none'); } else { (0, _tinySvg.attr)(gfx, 'display', 'block'); } }; GraphicsFactory.prototype.remove = function (element) { var gfx = this._elementRegistry.getGraphics(element); // remove (0, _tinySvg.remove)(gfx.parentNode); }; // helpers ////////////////////// function prependTo(newNode, parentNode, siblingNode) { parentNode.insertBefore(newNode, siblingNode || parentNode.firstChild); } },{"../util/GraphicsUtil":399,"../util/SvgTransformUtil":408,"min-dash":505,"min-dom":506,"tiny-svg":535}],251:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _draw = require('../draw'); var _draw2 = _interopRequireDefault(_draw); var _Canvas = require('./Canvas'); var _Canvas2 = _interopRequireDefault(_Canvas); var _ElementRegistry = require('./ElementRegistry'); var _ElementRegistry2 = _interopRequireDefault(_ElementRegistry); var _ElementFactory = require('./ElementFactory'); var _ElementFactory2 = _interopRequireDefault(_ElementFactory); var _EventBus = require('./EventBus'); var _EventBus2 = _interopRequireDefault(_EventBus); var _GraphicsFactory = require('./GraphicsFactory'); var _GraphicsFactory2 = _interopRequireDefault(_GraphicsFactory); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_draw2.default], __init__: ['canvas'], canvas: ['type', _Canvas2.default], elementRegistry: ['type', _ElementRegistry2.default], elementFactory: ['type', _ElementFactory2.default], eventBus: ['type', _EventBus2.default], graphicsFactory: ['type', _GraphicsFactory2.default] }; },{"../draw":255,"./Canvas":246,"./ElementFactory":247,"./ElementRegistry":248,"./EventBus":249,"./GraphicsFactory":250}],252:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BaseRenderer; var DEFAULT_RENDER_PRIORITY = 1000; /** * The base implementation of shape and connection renderers. * * @param {EventBus} eventBus * @param {Number} [renderPriority=1000] */ function BaseRenderer(eventBus, renderPriority) { var self = this; renderPriority = renderPriority || DEFAULT_RENDER_PRIORITY; eventBus.on(['render.shape', 'render.connection'], renderPriority, function (evt, context) { var type = evt.type, element = context.element, visuals = context.gfx; if (self.canRender(element)) { if (type === 'render.shape') { return self.drawShape(visuals, element); } else { return self.drawConnection(visuals, element); } } }); eventBus.on(['render.getShapePath', 'render.getConnectionPath'], renderPriority, function (evt, element) { if (self.canRender(element)) { if (evt.type === 'render.getShapePath') { return self.getShapePath(element); } else { return self.getConnectionPath(element); } } }); } /** * Should check whether *this* renderer can render * the element/connection. * * @param {element} element * * @returns {Boolean} */ BaseRenderer.prototype.canRender = function () {}; /** * Provides the shape's snap svg element to be drawn on the `canvas`. * * @param {djs.Graphics} visuals * @param {Shape} shape * * @returns {Snap.svg} [returns a Snap.svg paper element ] */ BaseRenderer.prototype.drawShape = function () {}; /** * Provides the shape's snap svg element to be drawn on the `canvas`. * * @param {djs.Graphics} visuals * @param {Connection} connection * * @returns {Snap.svg} [returns a Snap.svg paper element ] */ BaseRenderer.prototype.drawConnection = function () {}; /** * Gets the SVG path of a shape that represents it's visual bounds. * * @param {Shape} shape * * @return {string} svg path */ BaseRenderer.prototype.getShapePath = function () {}; /** * Gets the SVG path of a connection that represents it's visual bounds. * * @param {Connection} connection * * @return {string} svg path */ BaseRenderer.prototype.getConnectionPath = function () {}; },{}],253:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DefaultRenderer; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _BaseRenderer = require('./BaseRenderer'); var _BaseRenderer2 = _interopRequireDefault(_BaseRenderer); var _RenderUtil = require('../util/RenderUtil'); var _tinySvg = require('tiny-svg'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // apply default renderer with lowest possible priority // so that it only kicks in if noone else could render var DEFAULT_RENDER_PRIORITY = 1; /** * The default renderer used for shapes and connections. * * @param {EventBus} eventBus * @param {Styles} styles */ function DefaultRenderer(eventBus, styles) { // _BaseRenderer2.default.call(this, eventBus, DEFAULT_RENDER_PRIORITY); this.CONNECTION_STYLE = styles.style(['no-fill'], { strokeWidth: 5, stroke: 'fuchsia' }); this.SHAPE_STYLE = styles.style({ fill: 'white', stroke: 'fuchsia', strokeWidth: 2 }); } (0, _inherits2.default)(DefaultRenderer, _BaseRenderer2.default); DefaultRenderer.prototype.canRender = function () { return true; }; DefaultRenderer.prototype.drawShape = function drawShape(visuals, element) { var rect = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(rect, { x: 0, y: 0, width: element.width || 0, height: element.height || 0 }); (0, _tinySvg.attr)(rect, this.SHAPE_STYLE); (0, _tinySvg.append)(visuals, rect); return rect; }; DefaultRenderer.prototype.drawConnection = function drawConnection(visuals, connection) { var line = (0, _RenderUtil.createLine)(connection.waypoints, this.CONNECTION_STYLE); (0, _tinySvg.append)(visuals, line); return line; }; DefaultRenderer.prototype.getShapePath = function getShapePath(shape) { var x = shape.x, y = shape.y, width = shape.width, height = shape.height; var shapePath = [['M', x, y], ['l', width, 0], ['l', 0, height], ['l', -width, 0], ['z']]; return (0, _RenderUtil.componentsToPath)(shapePath); }; DefaultRenderer.prototype.getConnectionPath = function getConnectionPath(connection) { var waypoints = connection.waypoints; var idx, point, connectionPath = []; for (idx = 0; point = waypoints[idx]; idx++) { // take invisible docking into account // when creating the path point = point.original || point; connectionPath.push([idx === 0 ? 'M' : 'L', point.x, point.y]); } return (0, _RenderUtil.componentsToPath)(connectionPath); }; DefaultRenderer.$inject = ['eventBus', 'styles']; },{"../util/RenderUtil":407,"./BaseRenderer":252,"inherits":415,"tiny-svg":535}],254:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Styles; var _minDash = require('min-dash'); /** * A component that manages shape styles */ function Styles() { var defaultTraits = { 'no-fill': { fill: 'none' }, 'no-border': { strokeOpacity: 0.0 }, 'no-events': { pointerEvents: 'none' } }; var self = this; /** * Builds a style definition from a className, a list of traits and an object of additional attributes. * * @param {String} className * @param {Array} traits * @param {Object} additionalAttrs * * @return {Object} the style defintion */ this.cls = function (className, traits, additionalAttrs) { var attrs = this.style(traits, additionalAttrs); return (0, _minDash.assign)(attrs, { 'class': className }); }; /** * Builds a style definition from a list of traits and an object of additional attributes. * * @param {Array} traits * @param {Object} additionalAttrs * * @return {Object} the style defintion */ this.style = function (traits, additionalAttrs) { if (!(0, _minDash.isArray)(traits) && !additionalAttrs) { additionalAttrs = traits; traits = []; } var attrs = (0, _minDash.reduce)(traits, function (attrs, t) { return (0, _minDash.assign)(attrs, defaultTraits[t] || {}); }, {}); return additionalAttrs ? (0, _minDash.assign)(attrs, additionalAttrs) : attrs; }; this.computeStyle = function (custom, traits, defaultStyles) { if (!(0, _minDash.isArray)(traits)) { defaultStyles = traits; traits = []; } return self.style(traits || [], (0, _minDash.assign)({}, defaultStyles, custom || {})); }; } },{"min-dash":505}],255:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _DefaultRenderer = require('./DefaultRenderer'); var _DefaultRenderer2 = _interopRequireDefault(_DefaultRenderer); var _Styles = require('./Styles'); var _Styles2 = _interopRequireDefault(_Styles); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['defaultRenderer'], defaultRenderer: ['type', _DefaultRenderer2.default], styles: ['type', _Styles2.default] }; },{"./DefaultRenderer":253,"./Styles":254}],256:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AlignElements; var _minDash = require('min-dash'); function last(arr) { return arr && arr[arr.length - 1]; } function sortTopOrMiddle(element) { return element.y; } function sortLeftOrCenter(element) { return element.x; } /** * Sorting functions for different types of alignment * * @type {Object} * * @return {Function} */ var ALIGNMENT_SORTING = { left: sortLeftOrCenter, center: sortLeftOrCenter, right: function right(element) { return element.x + element.width; }, top: sortTopOrMiddle, middle: sortTopOrMiddle, bottom: function bottom(element) { return element.y + element.height; } }; function AlignElements(modeling) { this._modeling = modeling; } AlignElements.$inject = ['modeling']; /** * Get the relevant "axis" and "dimension" related to the current type of alignment * * @param {String} type left|right|center|top|bottom|middle * * @return {Object} { axis, dimension } */ AlignElements.prototype._getOrientationDetails = function (type) { var vertical = ['top', 'bottom', 'middle'], axis = 'x', dimension = 'width'; if (vertical.indexOf(type) !== -1) { axis = 'y'; dimension = 'height'; } return { axis: axis, dimension: dimension }; }; AlignElements.prototype._isType = function (type, types) { return types.indexOf(type) !== -1; }; /** * Get a point on the relevant axis where elements should align to * * @param {String} type left|right|center|top|bottom|middle * @param {Array} sortedElements * * @return {Object} */ AlignElements.prototype._alignmentPosition = function (type, sortedElements) { var orientation = this._getOrientationDetails(type), axis = orientation.axis, dimension = orientation.dimension, alignment = {}, centers = {}, hasSharedCenters = false, centeredElements, firstElement, lastElement; function getMiddleOrTop(first, last) { return Math.round((first[axis] + last[axis] + last[dimension]) / 2); } if (this._isType(type, ['left', 'top'])) { alignment[type] = sortedElements[0][axis]; } else if (this._isType(type, ['right', 'bottom'])) { lastElement = last(sortedElements); alignment[type] = lastElement[axis] + lastElement[dimension]; } else if (this._isType(type, ['center', 'middle'])) { // check if there is a center shared by more than one shape // if not, just take the middle of the range (0, _minDash.forEach)(sortedElements, function (element) { var center = element[axis] + Math.round(element[dimension] / 2); if (centers[center]) { centers[center].elements.push(element); } else { centers[center] = { elements: [element], center: center }; } }); centeredElements = (0, _minDash.sortBy)(centers, function (center) { if (center.elements.length > 1) { hasSharedCenters = true; } return center.elements.length; }); if (hasSharedCenters) { alignment[type] = last(centeredElements).center; return alignment; } firstElement = sortedElements[0]; sortedElements = (0, _minDash.sortBy)(sortedElements, function (element) { return element[axis] + element[dimension]; }); lastElement = last(sortedElements); alignment[type] = getMiddleOrTop(firstElement, lastElement); } return alignment; }; /** * Executes the alignment of a selection of elements * * @param {Array} elements [description] * @param {String} type left|right|center|top|bottom|middle */ AlignElements.prototype.trigger = function (elements, type) { var modeling = this._modeling; var filteredElements = (0, _minDash.filter)(elements, function (element) { return !(element.waypoints || element.host || element.labelTarget); }); var sortFn = ALIGNMENT_SORTING[type]; var sortedElements = (0, _minDash.sortBy)(filteredElements, sortFn); var alignment = this._alignmentPosition(type, sortedElements); modeling.alignElements(sortedElements, alignment); }; },{"min-dash":505}],257:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _AlignElements = require('./AlignElements'); var _AlignElements2 = _interopRequireDefault(_AlignElements); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['alignElements'], alignElements: ['type', _AlignElements2.default] }; },{"./AlignElements":256}],258:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AttachSupport; var _minDash = require('min-dash'); var _Removal = require('../../util/Removal'); var _Collections = require('../../util/Collections'); var _AttachUtil = require('../../util/AttachUtil'); var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CommandInterceptor = require('../../command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 251, HIGH_PRIORITY = 1401; /** * Adds the notion of attached elements to the modeler. * * Optionally depends on `diagram-js/lib/features/move` to render * the attached elements during move preview. * * Optionally depends on `diagram-js/lib/features/label-support` * to render attached labels during move preview. * * @param {didi.Injector} injector * @param {EventBus} eventBus * @param {Rules} rules * @param {Modeling} modeling */ function AttachSupport(injector, eventBus, rules, modeling) { _CommandInterceptor2.default.call(this, eventBus); var movePreview = injector.get('movePreview', false); // remove all the attached elements from the shapes to be validated // add all the attached shapes to the overall list of moved shapes eventBus.on('shape.move.start', HIGH_PRIORITY, function (e) { var context = e.context, shapes = context.shapes, validatedShapes = context.validatedShapes; context.shapes = addAttached(shapes); context.validatedShapes = removeAttached(validatedShapes); }); // add attachers to the visual's group movePreview && eventBus.on('shape.move.start', LOW_PRIORITY, function (e) { var context = e.context, shapes = context.shapes, attachers = getAttachers(shapes); (0, _minDash.forEach)(attachers, function (attacher) { movePreview.makeDraggable(context, attacher, true); (0, _minDash.forEach)(attacher.labels, function (label) { movePreview.makeDraggable(context, label, true); }); }); }); // add all attachers to move closure this.preExecuted('elements.move', HIGH_PRIORITY, function (e) { var context = e.context, closure = context.closure, shapes = context.shapes, attachers = getAttachers(shapes); (0, _minDash.forEach)(attachers, function (attacher) { closure.add(attacher, closure.topLevel[attacher.host.id]); }); }); // perform the attaching after shapes are done moving this.postExecuted('elements.move', function (e) { var context = e.context, shapes = context.shapes, newHost = context.newHost, attachers; // we only support attachment / detachment of one element if (shapes.length > 1) { return; } if (newHost) { attachers = shapes; } else { attachers = (0, _minDash.filter)(shapes, function (s) { return !!s.host; }); } (0, _minDash.forEach)(attachers, function (attacher) { modeling.updateAttachment(attacher, newHost); }); }); // ensure invalid attachment connections are removed this.postExecuted('elements.move', function (e) { var shapes = e.context.shapes; (0, _minDash.forEach)(shapes, function (shape) { (0, _minDash.forEach)(shape.attachers, function (attacher) { // remove invalid outgoing connections (0, _minDash.forEach)(attacher.outgoing.slice(), function (connection) { var allowed = rules.allowed('connection.reconnectStart', { connection: connection, source: connection.source, target: connection.target }); if (!allowed) { modeling.removeConnection(connection); } }); // remove invalid incoming connections (0, _minDash.forEach)(attacher.incoming.slice(), function (connection) { var allowed = rules.allowed('connection.reconnectEnd', { connection: connection, source: connection.source, target: connection.target }); if (!allowed) { modeling.removeConnection(connection); } }); }); }); }); this.postExecute('shape.create', function (e) { var context = e.context, shape = context.shape, host = context.host; if (host) { modeling.updateAttachment(shape, host); } }); // update attachments if the host is replaced this.postExecute('shape.replace', function (e) { var context = e.context, oldShape = context.oldShape, newShape = context.newShape; // move the attachers to the new host (0, _Removal.saveClear)(oldShape.attachers, function (attacher) { var allowed = rules.allowed('elements.move', { target: newShape, shapes: [attacher] }); if (allowed === 'attach') { modeling.updateAttachment(attacher, newShape); } else { modeling.removeShape(attacher); } }); // move attachers if new host has different size if (newShape.attachers.length) { (0, _minDash.forEach)(newShape.attachers, function (attacher) { var delta = (0, _AttachUtil.getNewAttachShapeDelta)(attacher, oldShape, newShape); modeling.moveShape(attacher, delta, attacher.parent); }); } }); // move shape on host resize this.postExecute('shape.resize', function (event) { var context = event.context, shape = context.shape, oldBounds = context.oldBounds, newBounds = context.newBounds, attachers = shape.attachers; (0, _minDash.forEach)(attachers, function (attacher) { var delta = (0, _AttachUtil.getNewAttachShapeDelta)(attacher, oldBounds, newBounds); modeling.moveShape(attacher, delta, attacher.parent); (0, _minDash.forEach)(attacher.labels, function (label) { modeling.moveShape(label, delta, label.parent); }); }); }); // remove attachments this.preExecute('shape.delete', function (event) { var shape = event.context.shape; (0, _Removal.saveClear)(shape.attachers, function (attacher) { modeling.removeShape(attacher); }); if (shape.host) { modeling.updateAttachment(shape, null); } }); // Prevent attachers and their labels from moving, when the space tool is performed. // Otherwise the attachers and their labels would be moved twice. eventBus.on('spaceTool.move', function (event) { var context = event.context, initialized = context.initialized, attachSupportInitialized = context.attachSupportInitialized; if (!initialized || attachSupportInitialized) { return; } var movingShapes = context.movingShapes; // collect attachers whose host is not being moved using the space tool var staticAttachers = (0, _minDash.filter)(movingShapes, function (shape) { var host = shape.host; return host && movingShapes.indexOf(host) === -1; }); // remove attachers that are not going to be moved from moving shapes (0, _minDash.forEach)(staticAttachers, function (shape) { (0, _Collections.remove)(movingShapes, shape); (0, _minDash.forEach)(shape.labels, function (label) { (0, _Collections.remove)(movingShapes, shape.label); }); }); context.attachSupportInitialized = true; }); } (0, _inherits2.default)(AttachSupport, _CommandInterceptor2.default); AttachSupport.$inject = ['injector', 'eventBus', 'rules', 'modeling']; /** * Return attachers of the given shapes * * @param {Array} shapes * @return {Array} */ function getAttachers(shapes) { return (0, _minDash.flatten)((0, _minDash.map)(shapes, function (s) { return s.attachers || []; })); } /** * Return a combined list of elements and * attachers. * * @param {Array} elements * @return {Array} filtered */ function addAttached(elements) { var attachers = getAttachers(elements); return (0, _minDash.unionBy)('id', elements, attachers); } /** * Return a filtered list of elements that do not * contain attached elements with hosts being part * of the selection. * * @param {Array} elements * * @return {Array} filtered */ function removeAttached(elements) { var ids = (0, _minDash.groupBy)(elements, 'id'); return (0, _minDash.filter)(elements, function (element) { while (element) { // host in selection if (element.host && ids[element.host.id]) { return false; } element = element.parent; } return true; }); } },{"../../command/CommandInterceptor":243,"../../util/AttachUtil":391,"../../util/Collections":393,"../../util/Removal":406,"inherits":415,"min-dash":505}],259:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _rules = require('../rules'); var _rules2 = _interopRequireDefault(_rules); var _AttachSupport = require('./AttachSupport'); var _AttachSupport2 = _interopRequireDefault(_AttachSupport); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_rules2.default], __init__: ['attachSupport'], attachSupport: ['type', _AttachSupport2.default] }; },{"../rules":355,"./AttachSupport":258}],260:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AutoResize; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _Elements = require('../../util/Elements'); var _LayoutUtil = require('../../layout/LayoutUtil'); var _minDash = require('min-dash'); var _CommandInterceptor = require('../../command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * An auto resize component that takes care of expanding a parent element * if child elements are created or moved close the parents edge. * * @param {EventBus} eventBus * @param {ElementRegistry} elementRegistry * @param {Modeling} modeling * @param {Rules} rules */ function AutoResize(eventBus, elementRegistry, modeling, rules) { _CommandInterceptor2.default.call(this, eventBus); this._elementRegistry = elementRegistry; this._modeling = modeling; this._rules = rules; var self = this; this.postExecuted(['shape.create'], function (event) { var context = event.context, hints = context.hints, shape = context.shape, parent = context.parent || context.newParent; if (hints && (hints.root === false || hints.autoResize === false)) { return; } self._expand([shape], parent); }); this.postExecuted(['elements.move'], function (event) { var context = event.context, elements = (0, _minDash.flatten)((0, _minDash.values)(context.closure.topLevel)), hints = context.hints; var autoResize = hints ? hints.autoResize : true; if (autoResize === false) { return; } var expandings = (0, _minDash.groupBy)(elements, function (element) { return element.parent.id; }); (0, _minDash.forEach)(expandings, function (elements, parentId) { // optionally filter elements to be considered when resizing if ((0, _minDash.isArray)(autoResize)) { elements = elements.filter(function (element) { return autoResize.indexOf(element) !== -1; }); } self._expand(elements, parentId); }); }); this.postExecuted(['shape.toggleCollapse'], function (event) { var context = event.context, hints = context.hints, shape = context.shape; if (hints && (hints.root === false || hints.autoResize === false)) { return; } if (shape.collapsed) { return; } self._expand(shape.children || [], shape); }); this.postExecuted(['shape.resize'], function (event) { var context = event.context, hints = context.hints, shape = context.shape, parent = shape.parent; if (hints && (hints.root === false || hints.autoResize === false)) { return; } if (parent) { self._expand([shape], parent); } }); } AutoResize.$inject = ['eventBus', 'elementRegistry', 'modeling', 'rules']; (0, _inherits2.default)(AutoResize, _CommandInterceptor2.default); /** * Calculate the new bounds of the target shape, given * a number of elements have been moved or added into the parent. * * This method considers the current size, the added elements as well as * the provided padding for the new bounds. * * @param {Array} elements * @param {djs.model.Shape} target */ AutoResize.prototype._getOptimalBounds = function (elements, target) { var offset = this.getOffset(target), padding = this.getPadding(target); var elementsTrbl = (0, _LayoutUtil.asTRBL)((0, _Elements.getBBox)(elements)), targetTrbl = (0, _LayoutUtil.asTRBL)(target); var newTrbl = {}; if (elementsTrbl.top - targetTrbl.top < padding.top) { newTrbl.top = elementsTrbl.top - offset.top; } if (elementsTrbl.left - targetTrbl.left < padding.left) { newTrbl.left = elementsTrbl.left - offset.left; } if (targetTrbl.right - elementsTrbl.right < padding.right) { newTrbl.right = elementsTrbl.right + offset.right; } if (targetTrbl.bottom - elementsTrbl.bottom < padding.bottom) { newTrbl.bottom = elementsTrbl.bottom + offset.bottom; } return (0, _LayoutUtil.asBounds)((0, _minDash.assign)({}, targetTrbl, newTrbl)); }; /** * Expand the target shape respecting rules, offset and padding * * @param {Array} elements * @param {djs.model.Shape|String} target|targetId */ AutoResize.prototype._expand = function (elements, target) { if (typeof target === 'string') { target = this._elementRegistry.get(target); } var allowed = this._rules.allowed('element.autoResize', { elements: elements, target: target }); if (!allowed) { return; } // calculate the new bounds var newBounds = this._getOptimalBounds(elements, target); if (!boundsChanged(newBounds, target)) { return; } // resize the parent shape this.resize(target, newBounds); var parent = target.parent; // recursively expand parent elements if (parent) { this._expand([target], parent); } }; /** * Get the amount to expand the given shape in each direction. * * @param {djs.model.Shape} shape * * @return {Object} {top, bottom, left, right} */ AutoResize.prototype.getOffset = function (shape) { return { top: 60, bottom: 60, left: 100, right: 100 }; }; /** * Get the activation threshold for each side for which * resize triggers. * * @param {djs.model.Shape} shape * * @return {Object} {top, bottom, left, right} */ AutoResize.prototype.getPadding = function (shape) { return { top: 2, bottom: 2, left: 15, right: 15 }; }; /** * Perform the actual resize operation. * * @param {djs.model.Shape} target * @param {Object} newBounds */ AutoResize.prototype.resize = function (target, newBounds) { this._modeling.resizeShape(target, newBounds); }; function boundsChanged(newBounds, oldBounds) { return newBounds.x !== oldBounds.x || newBounds.y !== oldBounds.y || newBounds.width !== oldBounds.width || newBounds.height !== oldBounds.height; } },{"../../command/CommandInterceptor":243,"../../layout/LayoutUtil":380,"../../util/Elements":396,"inherits":415,"min-dash":505}],261:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AutoResizeProvider; var _RuleProvider = require('../rules/RuleProvider'); var _RuleProvider2 = _interopRequireDefault(_RuleProvider); var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * This is a base rule provider for the element.autoResize rule. */ function AutoResizeProvider(eventBus) { _RuleProvider2.default.call(this, eventBus); var self = this; this.addRule('element.autoResize', function (context) { return self.canResize(context.elements, context.target); }); } AutoResizeProvider.$inject = ['eventBus']; (0, _inherits2.default)(AutoResizeProvider, _RuleProvider2.default); /** * Needs to be implemented by sub classes to allow actual auto resize * * @param {Array} elements * @param {djs.model.Shape} target * * @return {Boolean} */ AutoResizeProvider.prototype.canResize = function (elements, target) { return false; }; },{"../rules/RuleProvider":353,"inherits":415}],262:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AutoScroll; var _minDash = require('min-dash'); var _Event = require('../../util/Event'); /** * Initiates canvas scrolling if current cursor point is close to a border. * Cancelled when current point moves back inside the scrolling borders * or cancelled manually. * * Default options : * scrollThresholdIn: [ 20, 20, 20, 20 ], * scrollThresholdOut: [ 0, 0, 0, 0 ], * scrollRepeatTimeout: 15, * scrollStep: 10 * * Threshold order: * [ left, top, right, bottom ] */ function AutoScroll(config, eventBus, canvas, mouseTracking) { this._canvas = canvas; this._mouseTracking = mouseTracking; this._opts = (0, _minDash.assign)({ scrollThresholdIn: [20, 20, 20, 20], scrollThresholdOut: [0, 0, 0, 0], scrollRepeatTimeout: 15, scrollStep: 10 }, config); var self = this; eventBus.on('drag.move', function (e) { var point = self._toBorderPoint(e); self.startScroll(point); }); eventBus.on(['drag.cleanup'], function () { self.stopScroll(); }); } AutoScroll.$inject = ['config.autoScroll', 'eventBus', 'canvas', 'mouseTracking']; /** * Starts scrolling loop. * Point is given in global scale in canvas container box plane. * * @param {Object} point { x: X, y: Y } */ AutoScroll.prototype.startScroll = function (point) { var canvas = this._canvas; var opts = this._opts; var self = this; var clientRect = canvas.getContainer().getBoundingClientRect(); var diff = [point.x, point.y, clientRect.width - point.x, clientRect.height - point.y]; this.stopScroll(); var dx = 0, dy = 0; for (var i = 0; i < 4; i++) { if (between(diff[i], opts.scrollThresholdOut[i], opts.scrollThresholdIn[i])) { if (i === 0) { dx = opts.scrollStep; } else if (i == 1) { dy = opts.scrollStep; } else if (i == 2) { dx = -opts.scrollStep; } else if (i == 3) { dy = -opts.scrollStep; } } } if (dx !== 0 || dy !== 0) { canvas.scroll({ dx: dx, dy: dy }); this._scrolling = setTimeout(function () { self.startScroll(point); }, opts.scrollRepeatTimeout); } }; function between(val, start, end) { if (start < val && val < end) { return true; } return false; } /** * Stops scrolling loop. */ AutoScroll.prototype.stopScroll = function () { clearTimeout(this._scrolling); }; /** * Overrides defaults options. * * @param {Object} options */ AutoScroll.prototype.setOptions = function (options) { this._opts = (0, _minDash.assign)({}, this._opts, options); }; /** * Converts event to a point in canvas container plane in global scale. * * @param {Event} event * @return {Point} */ AutoScroll.prototype._toBorderPoint = function (event) { var clientRect = this._canvas._container.getBoundingClientRect(); var globalPosition = (0, _Event.toPoint)(event.originalEvent); return { x: globalPosition.x - clientRect.left, y: globalPosition.y - clientRect.top }; }; },{"../../util/Event":397,"min-dash":505}],263:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _dragging = require('../dragging'); var _dragging2 = _interopRequireDefault(_dragging); var _mouseTracking = require('../mouse-tracking'); var _mouseTracking2 = _interopRequireDefault(_mouseTracking); var _AutoScroll = require('./AutoScroll'); var _AutoScroll2 = _interopRequireDefault(_AutoScroll); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_dragging2.default, _mouseTracking2.default], __init__: ['autoScroll'], autoScroll: ['type', _AutoScroll2.default] }; },{"../dragging":286,"../mouse-tracking":331,"./AutoScroll":262}],264:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BendpointMove; var _Geometry = require('../../util/Geometry'); var _BendpointUtil = require('./BendpointUtil'); var _tinySvg = require('tiny-svg'); var _SvgTransformUtil = require('../../util/SvgTransformUtil'); var MARKER_OK = 'connect-ok', MARKER_NOT_OK = 'connect-not-ok', MARKER_CONNECT_HOVER = 'connect-hover', MARKER_CONNECT_UPDATING = 'djs-updating'; var COMMAND_BENDPOINT_UPDATE = 'connection.updateWaypoints', COMMAND_RECONNECT_START = 'connection.reconnectStart', COMMAND_RECONNECT_END = 'connection.reconnectEnd'; var round = Math.round; /** * A component that implements moving of bendpoints */ function BendpointMove(injector, eventBus, canvas, dragging, graphicsFactory, rules, modeling) { // optional connection docking integration var connectionDocking = injector.get('connectionDocking', false); // API this.start = function (event, connection, bendpointIndex, insert) { var type, context, waypoints = connection.waypoints, gfx = canvas.getGraphics(connection); if (!insert && bendpointIndex === 0) { type = COMMAND_RECONNECT_START; } else if (!insert && bendpointIndex === waypoints.length - 1) { type = COMMAND_RECONNECT_END; } else { type = COMMAND_BENDPOINT_UPDATE; } context = { connection: connection, bendpointIndex: bendpointIndex, insert: insert, type: type }; dragging.init(event, 'bendpoint.move', { data: { connection: connection, connectionGfx: gfx, context: context } }); }; // DRAGGING IMPLEMENTATION function redrawConnection(data) { graphicsFactory.update('connection', data.connection, data.connectionGfx); } function filterRedundantWaypoints(waypoints) { // alter copy of waypoints, not original waypoints = waypoints.slice(); var idx = 0, point, previousPoint, nextPoint; while (waypoints[idx]) { point = waypoints[idx]; previousPoint = waypoints[idx - 1]; nextPoint = waypoints[idx + 1]; if ((0, _Geometry.pointDistance)(point, nextPoint) === 0 || (0, _Geometry.pointsOnLine)(previousPoint, nextPoint, point)) { // remove point, if overlapping with {nextPoint} // or on line with {previousPoint} -> {point} -> {nextPoint} waypoints.splice(idx, 1); } else { idx++; } } return waypoints; } eventBus.on('bendpoint.move.start', function (e) { var context = e.context, connection = context.connection, originalWaypoints = connection.waypoints, waypoints = originalWaypoints.slice(), insert = context.insert, idx = context.bendpointIndex; context.originalWaypoints = originalWaypoints; if (insert) { // insert placeholder for bendpoint to-be-added waypoints.splice(idx, 0, null); } connection.waypoints = waypoints; // add dragger gfx context.draggerGfx = (0, _BendpointUtil.addBendpoint)(canvas.getLayer('overlays')); (0, _tinySvg.classes)(context.draggerGfx).add('djs-dragging'); canvas.addMarker(connection, MARKER_CONNECT_UPDATING); }); eventBus.on('bendpoint.move.hover', function (e) { var context = e.context; context.hover = e.hover; if (e.hover) { canvas.addMarker(e.hover, MARKER_CONNECT_HOVER); // asks whether reconnect / bendpoint move / bendpoint add // is allowed at the given position var allowed = context.allowed = rules.allowed(context.type, context); if (allowed) { canvas.removeMarker(context.hover, MARKER_NOT_OK); canvas.addMarker(context.hover, MARKER_OK); context.target = context.hover; } else if (allowed === false) { canvas.removeMarker(context.hover, MARKER_OK); canvas.addMarker(context.hover, MARKER_NOT_OK); context.target = null; } } }); eventBus.on(['bendpoint.move.out', 'bendpoint.move.cleanup'], function (e) { // remove connect marker // if it was added var hover = e.context.hover; if (hover) { canvas.removeMarker(hover, MARKER_CONNECT_HOVER); canvas.removeMarker(hover, e.context.target ? MARKER_OK : MARKER_NOT_OK); } }); eventBus.on('bendpoint.move.move', function (e) { var context = e.context, moveType = context.type, connection = e.connection, source, target; connection.waypoints[context.bendpointIndex] = { x: e.x, y: e.y }; if (connectionDocking) { if (context.hover) { if (moveType === COMMAND_RECONNECT_START) { source = context.hover; } if (moveType === COMMAND_RECONNECT_END) { target = context.hover; } } connection.waypoints = connectionDocking.getCroppedWaypoints(connection, source, target); } // add dragger gfx (0, _SvgTransformUtil.translate)(context.draggerGfx, e.x, e.y); redrawConnection(e); }); eventBus.on(['bendpoint.move.end', 'bendpoint.move.cancel'], function (e) { var context = e.context, hover = context.hover, connection = context.connection; // remove dragger gfx (0, _tinySvg.remove)(context.draggerGfx); context.newWaypoints = connection.waypoints.slice(); connection.waypoints = context.originalWaypoints; canvas.removeMarker(connection, MARKER_CONNECT_UPDATING); if (hover) { canvas.removeMarker(hover, MARKER_OK); canvas.removeMarker(hover, MARKER_NOT_OK); } }); eventBus.on('bendpoint.move.end', function (e) { var context = e.context, waypoints = context.newWaypoints, bendpointIndex = context.bendpointIndex, bendpoint = waypoints[bendpointIndex], allowed = context.allowed, hints; // ensure we have actual pixel values bendpoint // coordinates (important when zoom level was > 1 during move) bendpoint.x = round(bendpoint.x); bendpoint.y = round(bendpoint.y); if (allowed && context.type === COMMAND_RECONNECT_START) { modeling.reconnectStart(context.connection, context.target, bendpoint); } else if (allowed && context.type === COMMAND_RECONNECT_END) { modeling.reconnectEnd(context.connection, context.target, bendpoint); } else if (allowed !== false && context.type === COMMAND_BENDPOINT_UPDATE) { // pass hints on the actual moved bendpoint // this is useful for connection and label layouting hints = { bendpointMove: { insert: e.context.insert, bendpointIndex: bendpointIndex } }; modeling.updateWaypoints(context.connection, filterRedundantWaypoints(waypoints), hints); } else { redrawConnection(e); return false; } }); eventBus.on('bendpoint.move.cancel', function (e) { redrawConnection(e); }); } BendpointMove.$inject = ['injector', 'eventBus', 'canvas', 'dragging', 'graphicsFactory', 'rules', 'modeling']; },{"../../util/Geometry":398,"../../util/SvgTransformUtil":408,"./BendpointUtil":266,"tiny-svg":535}],265:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BendpointSnapping; var _minDash = require('min-dash'); var abs = Math.abs, round = Math.round; var TOLERANCE = 10; function BendpointSnapping(eventBus) { function snapTo(values, value) { if ((0, _minDash.isArray)(values)) { var i = values.length; while (i--) { if (abs(values[i] - value) <= TOLERANCE) { return values[i]; } } } else { values = +values; var rem = value % values; if (rem < TOLERANCE) { return value - rem; } if (rem > values - TOLERANCE) { return value - rem + values; } } return value; } function mid(element) { if (element.width) { return { x: round(element.width / 2 + element.x), y: round(element.height / 2 + element.y) }; } } // connection segment snapping ////////////////////// function getConnectionSegmentSnaps(context) { var snapPoints = context.snapPoints, connection = context.connection, waypoints = connection.waypoints, segmentStart = context.segmentStart, segmentStartIndex = context.segmentStartIndex, segmentEnd = context.segmentEnd, segmentEndIndex = context.segmentEndIndex, axis = context.axis; if (snapPoints) { return snapPoints; } var referenceWaypoints = [waypoints[segmentStartIndex - 1], segmentStart, segmentEnd, waypoints[segmentEndIndex + 1]]; if (segmentStartIndex < 2) { referenceWaypoints.unshift(mid(connection.source)); } if (segmentEndIndex > waypoints.length - 3) { referenceWaypoints.unshift(mid(connection.target)); } context.snapPoints = snapPoints = { horizontal: [], vertical: [] }; (0, _minDash.forEach)(referenceWaypoints, function (p) { // we snap on existing bendpoints only, // not placeholders that are inserted during add if (p) { p = p.original || p; if (axis === 'y') { snapPoints.horizontal.push(p.y); } if (axis === 'x') { snapPoints.vertical.push(p.x); } } }); return snapPoints; } eventBus.on('connectionSegment.move.move', 1500, function (event) { var context = event.context, snapPoints = getConnectionSegmentSnaps(context), x = event.x, y = event.y, sx, sy; if (!snapPoints) { return; } // snap sx = snapTo(snapPoints.vertical, x); sy = snapTo(snapPoints.horizontal, y); // correction x/y var cx = x - sx, cy = y - sy; // update delta (0, _minDash.assign)(event, { dx: event.dx - cx, dy: event.dy - cy, x: sx, y: sy }); }); // bendpoint snapping ////////////////////// function getBendpointSnaps(context) { var snapPoints = context.snapPoints, waypoints = context.connection.waypoints, bendpointIndex = context.bendpointIndex; if (snapPoints) { return snapPoints; } var referenceWaypoints = [waypoints[bendpointIndex - 1], waypoints[bendpointIndex + 1]]; context.snapPoints = snapPoints = { horizontal: [], vertical: [] }; (0, _minDash.forEach)(referenceWaypoints, function (p) { // we snap on existing bendpoints only, // not placeholders that are inserted during add if (p) { p = p.original || p; snapPoints.horizontal.push(p.y); snapPoints.vertical.push(p.x); } }); return snapPoints; } eventBus.on('bendpoint.move.move', 1500, function (event) { var context = event.context, snapPoints = getBendpointSnaps(context), target = context.target, targetMid = target && mid(target), x = event.x, y = event.y, sx, sy; if (!snapPoints) { return; } // snap sx = snapTo(targetMid ? snapPoints.vertical.concat([targetMid.x]) : snapPoints.vertical, x); sy = snapTo(targetMid ? snapPoints.horizontal.concat([targetMid.y]) : snapPoints.horizontal, y); // correction x/y var cx = x - sx, cy = y - sy; // update delta (0, _minDash.assign)(event, { dx: event.dx - cx, dy: event.dy - cy, x: event.x - cx, y: event.y - cy }); }); } BendpointSnapping.$inject = ['eventBus']; },{"min-dash":505}],266:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.SEGMENT_DRAGGER_CLS = exports.BENDPOINT_CLS = undefined; exports.toCanvasCoordinates = toCanvasCoordinates; exports.addBendpoint = addBendpoint; exports.addSegmentDragger = addSegmentDragger; var _Event = require('../../util/Event'); var _Geometry = require('../../util/Geometry'); var _tinySvg = require('tiny-svg'); var _SvgTransformUtil = require('../../util/SvgTransformUtil'); var BENDPOINT_CLS = exports.BENDPOINT_CLS = 'djs-bendpoint'; var SEGMENT_DRAGGER_CLS = exports.SEGMENT_DRAGGER_CLS = 'djs-segment-dragger'; function toCanvasCoordinates(canvas, event) { var position = (0, _Event.toPoint)(event), clientRect = canvas._container.getBoundingClientRect(), offset; // canvas relative position offset = { x: clientRect.left, y: clientRect.top }; // update actual event payload with canvas relative measures var viewbox = canvas.viewbox(); return { x: viewbox.x + (position.x - offset.x) / viewbox.scale, y: viewbox.y + (position.y - offset.y) / viewbox.scale }; } function addBendpoint(parentGfx, cls) { var groupGfx = (0, _tinySvg.create)('g'); (0, _tinySvg.classes)(groupGfx).add(BENDPOINT_CLS); (0, _tinySvg.append)(parentGfx, groupGfx); var visual = (0, _tinySvg.create)('circle'); (0, _tinySvg.attr)(visual, { cx: 0, cy: 0, r: 4 }); (0, _tinySvg.classes)(visual).add('djs-visual'); (0, _tinySvg.append)(groupGfx, visual); var hit = (0, _tinySvg.create)('circle'); (0, _tinySvg.attr)(hit, { cx: 0, cy: 0, r: 10 }); (0, _tinySvg.classes)(hit).add('djs-hit'); (0, _tinySvg.append)(groupGfx, hit); if (cls) { (0, _tinySvg.classes)(groupGfx).add(cls); } return groupGfx; } function createParallelDragger(parentGfx, position, alignment) { var draggerGfx = (0, _tinySvg.create)('g'); (0, _tinySvg.append)(parentGfx, draggerGfx); var width = 14, height = 3, padding = 6, hitWidth = width + padding, hitHeight = height + padding; var visual = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(visual, { x: -width / 2, y: -height / 2, width: width, height: height }); (0, _tinySvg.classes)(visual).add('djs-visual'); (0, _tinySvg.append)(draggerGfx, visual); var hit = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(hit, { x: -hitWidth / 2, y: -hitHeight / 2, width: hitWidth, height: hitHeight }); (0, _tinySvg.classes)(hit).add('djs-hit'); (0, _tinySvg.append)(draggerGfx, hit); (0, _SvgTransformUtil.rotate)(draggerGfx, alignment === 'h' ? 90 : 0, 0, 0); return draggerGfx; } function addSegmentDragger(parentGfx, segmentStart, segmentEnd) { var groupGfx = (0, _tinySvg.create)('g'), mid = (0, _Geometry.getMidPoint)(segmentStart, segmentEnd), alignment = (0, _Geometry.pointsAligned)(segmentStart, segmentEnd); (0, _tinySvg.append)(parentGfx, groupGfx); createParallelDragger(groupGfx, mid, alignment); (0, _tinySvg.classes)(groupGfx).add(SEGMENT_DRAGGER_CLS); (0, _tinySvg.classes)(groupGfx).add(alignment === 'h' ? 'vertical' : 'horizontal'); (0, _SvgTransformUtil.translate)(groupGfx, mid.x, mid.y); return groupGfx; } },{"../../util/Event":397,"../../util/Geometry":398,"../../util/SvgTransformUtil":408,"tiny-svg":535}],267:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Bendpoints; var _minDash = require('min-dash'); var _minDom = require('min-dom'); var _BendpointUtil = require('./BendpointUtil'); var _css = require('css.escape'); var _css2 = _interopRequireDefault(_css); var _Geometry = require('../../util/Geometry'); var _LineIntersection = require('../../util/LineIntersection'); var _tinySvg = require('tiny-svg'); var _SvgTransformUtil = require('../../util/SvgTransformUtil'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A service that adds editable bendpoints to connections. */ function Bendpoints(eventBus, canvas, interactionEvents, bendpointMove, connectionSegmentMove) { function getConnectionIntersection(waypoints, event) { var localPosition = (0, _BendpointUtil.toCanvasCoordinates)(canvas, event), intersection = (0, _LineIntersection.getApproxIntersection)(waypoints, localPosition); return intersection; } function isIntersectionMiddle(intersection, waypoints, treshold) { var idx = intersection.index, p = intersection.point, p0, p1, mid, aligned, xDelta, yDelta; if (idx <= 0 || intersection.bendpoint) { return false; } p0 = waypoints[idx - 1]; p1 = waypoints[idx]; mid = (0, _Geometry.getMidPoint)(p0, p1), aligned = (0, _Geometry.pointsAligned)(p0, p1); xDelta = Math.abs(p.x - mid.x); yDelta = Math.abs(p.y - mid.y); return aligned && xDelta <= treshold && yDelta <= treshold; } function activateBendpointMove(event, connection) { var waypoints = connection.waypoints, intersection = getConnectionIntersection(waypoints, event); if (!intersection) { return; } if (isIntersectionMiddle(intersection, waypoints, 10)) { connectionSegmentMove.start(event, connection, intersection.index); } else { bendpointMove.start(event, connection, intersection.index, !intersection.bendpoint); } // we've handled the event return true; } function bindInteractionEvents(node, eventName, element) { _minDom.event.bind(node, eventName, function (event) { interactionEvents.triggerMouseEvent(eventName, event, element); event.stopPropagation(); }); } function getBendpointsContainer(element, create) { var layer = canvas.getLayer('overlays'), gfx = (0, _minDom.query)('.djs-bendpoints[data-element-id="' + (0, _css2.default)(element.id) + '"]', layer); if (!gfx && create) { gfx = (0, _tinySvg.create)('g'); (0, _tinySvg.attr)(gfx, { 'data-element-id': element.id }); (0, _tinySvg.classes)(gfx).add('djs-bendpoints'); (0, _tinySvg.append)(layer, gfx); bindInteractionEvents(gfx, 'mousedown', element); bindInteractionEvents(gfx, 'click', element); bindInteractionEvents(gfx, 'dblclick', element); } return gfx; } function createBendpoints(gfx, connection) { connection.waypoints.forEach(function (p, idx) { var bendpoint = (0, _BendpointUtil.addBendpoint)(gfx); (0, _tinySvg.append)(gfx, bendpoint); (0, _SvgTransformUtil.translate)(bendpoint, p.x, p.y); }); // add floating bendpoint (0, _BendpointUtil.addBendpoint)(gfx, 'floating'); } function createSegmentDraggers(gfx, connection) { var waypoints = connection.waypoints; var segmentStart, segmentEnd; for (var i = 1; i < waypoints.length; i++) { segmentStart = waypoints[i - 1]; segmentEnd = waypoints[i]; if ((0, _Geometry.pointsAligned)(segmentStart, segmentEnd)) { (0, _BendpointUtil.addSegmentDragger)(gfx, segmentStart, segmentEnd); } } } function clearBendpoints(gfx) { (0, _minDash.forEach)((0, _minDom.queryAll)('.' + _BendpointUtil.BENDPOINT_CLS, gfx), function (node) { (0, _tinySvg.remove)(node); }); } function clearSegmentDraggers(gfx) { (0, _minDash.forEach)((0, _minDom.queryAll)('.' + _BendpointUtil.SEGMENT_DRAGGER_CLS, gfx), function (node) { (0, _tinySvg.remove)(node); }); } function addHandles(connection) { var gfx = getBendpointsContainer(connection); if (!gfx) { gfx = getBendpointsContainer(connection, true); createBendpoints(gfx, connection); createSegmentDraggers(gfx, connection); } return gfx; } function updateHandles(connection) { var gfx = getBendpointsContainer(connection); if (gfx) { clearSegmentDraggers(gfx); clearBendpoints(gfx); createSegmentDraggers(gfx, connection); createBendpoints(gfx, connection); } } eventBus.on('connection.changed', function (event) { updateHandles(event.element); }); eventBus.on('connection.remove', function (event) { var gfx = getBendpointsContainer(event.element); if (gfx) { (0, _tinySvg.remove)(gfx); } }); eventBus.on('element.marker.update', function (event) { var element = event.element, bendpointsGfx; if (!element.waypoints) { return; } bendpointsGfx = addHandles(element); if (event.add) { (0, _tinySvg.classes)(bendpointsGfx).add(event.marker); } else { (0, _tinySvg.classes)(bendpointsGfx).remove(event.marker); } }); eventBus.on('element.mousemove', function (event) { var element = event.element, waypoints = element.waypoints, bendpointsGfx, floating, intersection; if (waypoints) { bendpointsGfx = getBendpointsContainer(element, true); floating = (0, _minDom.query)('.floating', bendpointsGfx); if (!floating) { return; } intersection = getConnectionIntersection(waypoints, event.originalEvent); if (intersection) { (0, _SvgTransformUtil.translate)(floating, intersection.point.x, intersection.point.y); } } }); eventBus.on('element.mousedown', function (event) { var originalEvent = event.originalEvent, element = event.element, waypoints = element.waypoints; if (!waypoints) { return; } return activateBendpointMove(originalEvent, element, waypoints); }); eventBus.on('selection.changed', function (event) { var newSelection = event.newSelection, primary = newSelection[0]; if (primary && primary.waypoints) { addHandles(primary); } }); eventBus.on('element.hover', function (event) { var element = event.element; if (element.waypoints) { addHandles(element); interactionEvents.registerEvent(event.gfx, 'mousemove', 'element.mousemove'); } }); eventBus.on('element.out', function (event) { interactionEvents.unregisterEvent(event.gfx, 'mousemove', 'element.mousemove'); }); // update bendpoint container data attribute on element ID change eventBus.on('element.updateId', function (context) { var element = context.element, newId = context.newId; if (element.waypoints) { var bendpointContainer = getBendpointsContainer(element); if (bendpointContainer) { (0, _tinySvg.attr)(bendpointContainer, { 'data-element-id': newId }); } } }); // API this.addHandles = addHandles; this.updateHandles = updateHandles; this.getBendpointsContainer = getBendpointsContainer; } Bendpoints.$inject = ['eventBus', 'canvas', 'interactionEvents', 'bendpointMove', 'connectionSegmentMove']; },{"../../util/Geometry":398,"../../util/LineIntersection":401,"../../util/SvgTransformUtil":408,"./BendpointUtil":266,"css.escape":237,"min-dash":505,"min-dom":506,"tiny-svg":535}],268:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ConnectionSegmentMove; var _Geometry = require('../../util/Geometry'); var _BendpointUtil = require('./BendpointUtil'); var _LayoutUtil = require('../../layout/LayoutUtil'); var _tinySvg = require('tiny-svg'); var _SvgTransformUtil = require('../../util/SvgTransformUtil'); var MARKER_CONNECT_HOVER = 'connect-hover', MARKER_CONNECT_UPDATING = 'djs-updating'; function axisAdd(point, axis, delta) { return axisSet(point, axis, point[axis] + delta); } function axisSet(point, axis, value) { return { x: axis === 'x' ? value : point.x, y: axis === 'y' ? value : point.y }; } function axisFenced(position, segmentStart, segmentEnd, axis) { var maxValue = Math.max(segmentStart[axis], segmentEnd[axis]), minValue = Math.min(segmentStart[axis], segmentEnd[axis]); var padding = 20; var fencedValue = Math.min(Math.max(minValue + padding, position[axis]), maxValue - padding); return axisSet(segmentStart, axis, fencedValue); } function flipAxis(axis) { return axis === 'x' ? 'y' : 'x'; } /** * Get the docking point on the given element. * * Compute a reasonable docking, if non exists. * * @param {Point} point * @param {djs.model.Shape} referenceElement * @param {String} moveAxis (x|y) * * @return {Point} */ function getDocking(point, referenceElement, moveAxis) { var referenceMid, inverseAxis; if (point.original) { return point.original; } else { referenceMid = (0, _LayoutUtil.getMid)(referenceElement); inverseAxis = flipAxis(moveAxis); return axisSet(point, inverseAxis, referenceMid[inverseAxis]); } } /** * A component that implements moving of bendpoints */ function ConnectionSegmentMove(injector, eventBus, canvas, dragging, graphicsFactory, rules, modeling) { // optional connection docking integration var connectionDocking = injector.get('connectionDocking', false); // API this.start = function (event, connection, idx) { var context, gfx = canvas.getGraphics(connection), segmentStartIndex = idx - 1, segmentEndIndex = idx, waypoints = connection.waypoints, segmentStart = waypoints[segmentStartIndex], segmentEnd = waypoints[segmentEndIndex], direction, axis; direction = (0, _Geometry.pointsAligned)(segmentStart, segmentEnd); // do not move diagonal connection if (!direction) { return; } // the axis where we are going to move things axis = direction === 'v' ? 'y' : 'x'; if (segmentStartIndex === 0) { segmentStart = getDocking(segmentStart, connection.source, axis); } if (segmentEndIndex === waypoints.length - 1) { segmentEnd = getDocking(segmentEnd, connection.target, axis); } context = { connection: connection, segmentStartIndex: segmentStartIndex, segmentEndIndex: segmentEndIndex, segmentStart: segmentStart, segmentEnd: segmentEnd, axis: axis }; dragging.init(event, { x: (segmentStart.x + segmentEnd.x) / 2, y: (segmentStart.y + segmentEnd.y) / 2 }, 'connectionSegment.move', { cursor: axis === 'x' ? 'resize-ew' : 'resize-ns', data: { connection: connection, connectionGfx: gfx, context: context } }); }; /** * Crop connection if connection cropping is provided. * * @param {Connection} connection * @param {Array} newWaypoints * * @return {Array} cropped connection waypoints */ function cropConnection(connection, newWaypoints) { // crop connection, if docking service is provided only if (!connectionDocking) { return newWaypoints; } var oldWaypoints = connection.waypoints, croppedWaypoints; // temporary set new waypoints connection.waypoints = newWaypoints; croppedWaypoints = connectionDocking.getCroppedWaypoints(connection); // restore old waypoints connection.waypoints = oldWaypoints; return croppedWaypoints; } // DRAGGING IMPLEMENTATION function redrawConnection(data) { graphicsFactory.update('connection', data.connection, data.connectionGfx); } function updateDragger(context, segmentOffset, event) { var newWaypoints = context.newWaypoints, segmentStartIndex = context.segmentStartIndex + segmentOffset, segmentStart = newWaypoints[segmentStartIndex], segmentEndIndex = context.segmentEndIndex + segmentOffset, segmentEnd = newWaypoints[segmentEndIndex], axis = flipAxis(context.axis); // make sure the dragger does not move // outside the connection var draggerPosition = axisFenced(event, segmentStart, segmentEnd, axis); // update dragger (0, _SvgTransformUtil.translate)(context.draggerGfx, draggerPosition.x, draggerPosition.y); } /** * Filter waypoints for redundant ones (i.e. on the same axis). * Returns the filtered waypoints and the offset related to the segment move. * * @param {Array} waypoints * @param {Integer} segmentStartIndex of moved segment start * * @return {Object} { filteredWaypoints, segmentOffset } */ function filterRedundantWaypoints(waypoints, segmentStartIndex) { var segmentOffset = 0; var filteredWaypoints = waypoints.filter(function (r, idx) { if ((0, _Geometry.pointsOnLine)(waypoints[idx - 1], waypoints[idx + 1], r)) { // remove point and increment offset segmentOffset = idx <= segmentStartIndex ? segmentOffset - 1 : segmentOffset; return false; } // dont remove point return true; }); return { waypoints: filteredWaypoints, segmentOffset: segmentOffset }; } eventBus.on('connectionSegment.move.start', function (e) { var context = e.context, connection = e.connection, layer = canvas.getLayer('overlays'); context.originalWaypoints = connection.waypoints.slice(); // add dragger gfx context.draggerGfx = (0, _BendpointUtil.addSegmentDragger)(layer, context.segmentStart, context.segmentEnd); (0, _tinySvg.classes)(context.draggerGfx).add('djs-dragging'); canvas.addMarker(connection, MARKER_CONNECT_UPDATING); }); eventBus.on('connectionSegment.move.move', function (e) { var context = e.context, connection = context.connection, segmentStartIndex = context.segmentStartIndex, segmentEndIndex = context.segmentEndIndex, segmentStart = context.segmentStart, segmentEnd = context.segmentEnd, axis = context.axis; var newWaypoints = context.originalWaypoints.slice(), newSegmentStart = axisAdd(segmentStart, axis, e['d' + axis]), newSegmentEnd = axisAdd(segmentEnd, axis, e['d' + axis]); // original waypoint count and added / removed // from start waypoint delta. We use the later // to retrieve the updated segmentStartIndex / segmentEndIndex var waypointCount = newWaypoints.length, segmentOffset = 0; // move segment start / end by axis delta newWaypoints[segmentStartIndex] = newSegmentStart; newWaypoints[segmentEndIndex] = newSegmentEnd; var sourceToSegmentOrientation, targetToSegmentOrientation; // handle first segment if (segmentStartIndex < 2) { sourceToSegmentOrientation = (0, _LayoutUtil.getOrientation)(connection.source, newSegmentStart); // first bendpoint, remove first segment if intersecting if (segmentStartIndex === 1) { if (sourceToSegmentOrientation === 'intersect') { newWaypoints.shift(); newWaypoints[0] = newSegmentStart; segmentOffset--; } } // docking point, add segment if not intersecting anymore else { if (sourceToSegmentOrientation !== 'intersect') { newWaypoints.unshift(segmentStart); segmentOffset++; } } } // handle last segment if (segmentEndIndex > waypointCount - 3) { targetToSegmentOrientation = (0, _LayoutUtil.getOrientation)(connection.target, newSegmentEnd); // last bendpoint, remove last segment if intersecting if (segmentEndIndex === waypointCount - 2) { if (targetToSegmentOrientation === 'intersect') { newWaypoints.pop(); newWaypoints[newWaypoints.length - 1] = newSegmentEnd; } } // last bendpoint, remove last segment if intersecting else { if (targetToSegmentOrientation !== 'intersect') { newWaypoints.push(segmentEnd); } } } // update connection waypoints context.newWaypoints = connection.waypoints = cropConnection(connection, newWaypoints); // update dragger position updateDragger(context, segmentOffset, e); // save segmentOffset in context context.newSegmentStartIndex = segmentStartIndex + segmentOffset; // redraw connection redrawConnection(e); }); eventBus.on('connectionSegment.move.hover', function (e) { e.context.hover = e.hover; canvas.addMarker(e.hover, MARKER_CONNECT_HOVER); }); eventBus.on(['connectionSegment.move.out', 'connectionSegment.move.cleanup'], function (e) { // remove connect marker // if it was added var hover = e.context.hover; if (hover) { canvas.removeMarker(hover, MARKER_CONNECT_HOVER); } }); eventBus.on('connectionSegment.move.cleanup', function (e) { var context = e.context, connection = context.connection; // remove dragger gfx if (context.draggerGfx) { (0, _tinySvg.remove)(context.draggerGfx); } canvas.removeMarker(connection, MARKER_CONNECT_UPDATING); }); eventBus.on(['connectionSegment.move.cancel', 'connectionSegment.move.end'], function (e) { var context = e.context, connection = context.connection; connection.waypoints = context.originalWaypoints; redrawConnection(e); }); eventBus.on('connectionSegment.move.end', function (e) { var context = e.context, connection = context.connection, newWaypoints = context.newWaypoints, newSegmentStartIndex = context.newSegmentStartIndex; // ensure we have actual pixel values bendpoint // coordinates (important when zoom level was > 1 during move) newWaypoints = newWaypoints.map(function (p) { return { original: p.original, x: Math.round(p.x), y: Math.round(p.y) }; }); // apply filter redunant waypoints var filtered = filterRedundantWaypoints(newWaypoints, newSegmentStartIndex); // get filtered waypoints var filteredWaypoints = filtered.waypoints, croppedWaypoints = cropConnection(connection, filteredWaypoints), segmentOffset = filtered.segmentOffset; var hints = { segmentMove: { segmentStartIndex: context.segmentStartIndex, newSegmentStartIndex: newSegmentStartIndex + segmentOffset } }; modeling.updateWaypoints(connection, croppedWaypoints, hints); }); } ConnectionSegmentMove.$inject = ['injector', 'eventBus', 'canvas', 'dragging', 'graphicsFactory', 'rules', 'modeling']; },{"../../layout/LayoutUtil":380,"../../util/Geometry":398,"../../util/SvgTransformUtil":408,"./BendpointUtil":266,"tiny-svg":535}],269:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _dragging = require('../dragging'); var _dragging2 = _interopRequireDefault(_dragging); var _rules = require('../rules'); var _rules2 = _interopRequireDefault(_rules); var _Bendpoints = require('./Bendpoints'); var _Bendpoints2 = _interopRequireDefault(_Bendpoints); var _BendpointMove = require('./BendpointMove'); var _BendpointMove2 = _interopRequireDefault(_BendpointMove); var _ConnectionSegmentMove = require('./ConnectionSegmentMove'); var _ConnectionSegmentMove2 = _interopRequireDefault(_ConnectionSegmentMove); var _BendpointSnapping = require('./BendpointSnapping'); var _BendpointSnapping2 = _interopRequireDefault(_BendpointSnapping); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_dragging2.default, _rules2.default], __init__: ['bendpoints', 'bendpointSnapping'], bendpoints: ['type', _Bendpoints2.default], bendpointMove: ['type', _BendpointMove2.default], connectionSegmentMove: ['type', _ConnectionSegmentMove2.default], bendpointSnapping: ['type', _BendpointSnapping2.default] }; },{"../dragging":286,"../rules":355,"./BendpointMove":264,"./BendpointSnapping":265,"./Bendpoints":267,"./ConnectionSegmentMove":268}],270:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ChangeSupport; var _Elements = require('../../util/Elements'); /** * Adds change support to the diagram, including * *
    *
  • redrawing shapes and connections on change
  • *
* * @param {EventBus} eventBus * @param {Canvas} canvas * @param {ElementRegistry} elementRegistry * @param {GraphicsFactory} graphicsFactory */ function ChangeSupport(eventBus, canvas, elementRegistry, graphicsFactory) { // redraw shapes / connections on change eventBus.on('element.changed', function (event) { var element = event.element; // element might have been deleted and replaced by new element with same ID // thus check for parent of element except for root element if (element.parent || element === canvas.getRootElement()) { event.gfx = elementRegistry.getGraphics(element); } // shape + gfx may have been deleted if (!event.gfx) { return; } eventBus.fire((0, _Elements.getType)(element) + '.changed', event); }); eventBus.on('elements.changed', function (event) { var elements = event.elements; elements.forEach(function (e) { eventBus.fire('element.changed', { element: e }); }); graphicsFactory.updateContainments(elements); }); eventBus.on('shape.changed', function (event) { graphicsFactory.update('shape', event.element, event.gfx); }); eventBus.on('connection.changed', function (event) { graphicsFactory.update('connection', event.element, event.gfx); }); } ChangeSupport.$inject = ['eventBus', 'canvas', 'elementRegistry', 'graphicsFactory']; },{"../../util/Elements":396}],271:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _ChangeSupport = require('./ChangeSupport'); var _ChangeSupport2 = _interopRequireDefault(_ChangeSupport); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['changeSupport'], changeSupport: ['type', _ChangeSupport2.default] }; },{"./ChangeSupport":270}],272:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Clipboard; /** * A clip board stub */ function Clipboard() {} Clipboard.prototype.get = function () { return this._data; }; Clipboard.prototype.set = function (data) { this._data = data; }; Clipboard.prototype.clear = function () { var data = this._data; delete this._data; return data; }; Clipboard.prototype.isEmpty = function () { return !this._data; }; },{}],273:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _Clipboard = require('./Clipboard'); var _Clipboard2 = _interopRequireDefault(_Clipboard); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { clipboard: ['type', _Clipboard2.default] }; },{"./Clipboard":272}],274:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; exports.default = Connect; var _LayoutUtil = require('../../layout/LayoutUtil'); var _tinySvg = require('tiny-svg'); var MARKER_OK = 'connect-ok', MARKER_NOT_OK = 'connect-not-ok'; function Connect(eventBus, dragging, modeling, rules, canvas, graphicsFactory) { // TODO(nre): separate UI and events // rules function canConnect(source, target) { return rules.allowed('connection.create', { source: source, target: target }); } // layouting function crop(start, end, source, target) { var sourcePath = graphicsFactory.getShapePath(source), targetPath = target && graphicsFactory.getShapePath(target), connectionPath = graphicsFactory.getConnectionPath({ waypoints: [start, end] }); start = (0, _LayoutUtil.getElementLineIntersection)(sourcePath, connectionPath, true) || start; end = target && (0, _LayoutUtil.getElementLineIntersection)(targetPath, connectionPath, false) || end; return [start, end]; } // event handlers eventBus.on('connect.move', function (event) { var context = event.context, source = context.source, target = context.target, visual = context.visual, sourcePosition = context.sourcePosition, endPosition, waypoints; // update connection visuals during drag endPosition = { x: event.x, y: event.y }; waypoints = crop(sourcePosition, endPosition, source, target); (0, _tinySvg.attr)(visual, { 'points': [waypoints[0].x, waypoints[0].y, waypoints[1].x, waypoints[1].y] }); }); eventBus.on('connect.hover', function (event) { var context = event.context, source = context.source, hover = event.hover, canExecute; canExecute = context.canExecute = canConnect(source, hover); // simply ignore hover if (canExecute === null) { return; } context.target = hover; canvas.addMarker(hover, canExecute ? MARKER_OK : MARKER_NOT_OK); }); eventBus.on(['connect.out', 'connect.cleanup'], function (event) { var context = event.context; if (context.target) { canvas.removeMarker(context.target, context.canExecute ? MARKER_OK : MARKER_NOT_OK); } context.target = null; context.canExecute = false; }); eventBus.on('connect.cleanup', function (event) { var context = event.context; if (context.visual) { (0, _tinySvg.remove)(context.visual); } }); eventBus.on('connect.start', function (event) { var context = event.context, visual; visual = (0, _tinySvg.create)('polyline'); (0, _tinySvg.attr)(visual, { 'stroke': '#333', 'strokeDasharray': [1], 'strokeWidth': 2, 'pointer-events': 'none' }); (0, _tinySvg.append)(canvas.getDefaultLayer(), visual); context.visual = visual; }); eventBus.on('connect.end', function (event) { var context = event.context, source = context.source, sourcePosition = context.sourcePosition, target = context.target, targetPosition = { x: event.x, y: event.y }, canExecute = context.canExecute || canConnect(source, target); if (!canExecute) { return false; } var attrs = null, hints = { connectionStart: sourcePosition, connectionEnd: targetPosition }; if ((typeof canExecute === 'undefined' ? 'undefined' : _typeof(canExecute)) === 'object') { attrs = canExecute; } modeling.connect(source, target, attrs, hints); }); // API /** * Start connect operation. * * @param {DOMEvent} event * @param {djs.model.Base} source * @param {Point} [sourcePosition] * @param {Boolean} [autoActivate=false] */ this.start = function (event, source, sourcePosition, autoActivate) { if ((typeof sourcePosition === 'undefined' ? 'undefined' : _typeof(sourcePosition)) !== 'object') { autoActivate = sourcePosition; sourcePosition = (0, _LayoutUtil.getMid)(source); } dragging.init(event, 'connect', { autoActivate: autoActivate, data: { shape: source, context: { source: source, sourcePosition: sourcePosition } } }); }; } Connect.$inject = ['eventBus', 'dragging', 'modeling', 'rules', 'canvas', 'graphicsFactory']; },{"../../layout/LayoutUtil":380,"tiny-svg":535}],275:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _selection = require('../selection'); var _selection2 = _interopRequireDefault(_selection); var _rules = require('../rules'); var _rules2 = _interopRequireDefault(_rules); var _dragging = require('../dragging'); var _dragging2 = _interopRequireDefault(_dragging); var _Connect = require('./Connect'); var _Connect2 = _interopRequireDefault(_Connect); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_selection2.default, _rules2.default, _dragging2.default], connect: ['type', _Connect2.default] }; },{"../dragging":286,"../rules":355,"../selection":361,"./Connect":274}],276:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ContextPad; var _minDash = require('min-dash'); var _minDom = require('min-dom'); var entrySelector = '.entry'; /** * A context pad that displays element specific, contextual actions next * to a diagram element. * * @param {Object} config * @param {Boolean|Object} [config.scale={ min: 1.0, max: 1.5 }] * @param {Number} [config.scale.min] * @param {Number} [config.scale.max] * @param {EventBus} eventBus * @param {Overlays} overlays */ function ContextPad(config, eventBus, overlays) { this._providers = []; this._eventBus = eventBus; this._overlays = overlays; var scale = (0, _minDash.isDefined)(config && config.scale) ? config.scale : { min: 1, max: 1.5 }; this._overlaysConfig = { position: { right: -9, top: -6 }, scale: scale }; this._current = null; this._init(); } ContextPad.$inject = ['config.contextPad', 'eventBus', 'overlays']; /** * Registers events needed for interaction with other components */ ContextPad.prototype._init = function () { var eventBus = this._eventBus; var self = this; eventBus.on('selection.changed', function (e) { var selection = e.newSelection; if (selection.length === 1) { self.open(selection[0]); } else { self.close(); } }); eventBus.on('elements.delete', function (event) { var elements = event.elements; (0, _minDash.forEach)(elements, function (e) { if (self.isOpen(e)) { self.close(); } }); }); eventBus.on('element.changed', function (event) { var element = event.element, current = self._current; // force reopen if element for which we are currently opened changed if (current && current.element === element) { self.open(element, true); } }); }; /** * Register a provider with the context pad * * @param {ContextPadProvider} provider */ ContextPad.prototype.registerProvider = function (provider) { this._providers.push(provider); }; /** * Returns the context pad entries for a given element * * @param {djs.element.Base} element * * @return {Array} list of entries */ ContextPad.prototype.getEntries = function (element) { var entries = {}; // loop through all providers and their entries. // group entries by id so that overriding an entry is possible (0, _minDash.forEach)(this._providers, function (provider) { var e = provider.getContextPadEntries(element); (0, _minDash.forEach)(e, function (entry, id) { entries[id] = entry; }); }); return entries; }; /** * Trigger an action available on the opened context pad * * @param {String} action * @param {Event} event * @param {Boolean} [autoActivate=false] */ ContextPad.prototype.trigger = function (action, event, autoActivate) { var element = this._current.element, entries = this._current.entries, entry, handler, originalEvent, button = event.delegateTarget || event.target; if (!button) { return event.preventDefault(); } entry = entries[(0, _minDom.attr)(button, 'data-action')]; handler = entry.action; originalEvent = event.originalEvent || event; // simple action (via callback function) if ((0, _minDash.isFunction)(handler)) { if (action === 'click') { return handler(originalEvent, element, autoActivate); } } else { if (handler[action]) { return handler[action](originalEvent, element, autoActivate); } } // silence other actions event.preventDefault(); }; /** * Open the context pad for the given element * * @param {djs.model.Base} element * @param {Boolean} force if true, force reopening the context pad */ ContextPad.prototype.open = function (element, force) { if (!force && this.isOpen(element)) { return; } this.close(); this._updateAndOpen(element); }; ContextPad.prototype._updateAndOpen = function (element) { var entries = this.getEntries(element), pad = this.getPad(element), html = pad.html; (0, _minDash.forEach)(entries, function (entry, id) { var grouping = entry.group || 'default', control = (0, _minDom.domify)(entry.html || '
'), container; (0, _minDom.attr)(control, 'data-action', id); container = (0, _minDom.query)('[data-group=' + grouping + ']', html); if (!container) { container = (0, _minDom.domify)('
'); html.appendChild(container); } container.appendChild(control); if (entry.className) { addClasses(control, entry.className); } if (entry.title) { (0, _minDom.attr)(control, 'title', entry.title); } if (entry.imageUrl) { control.appendChild((0, _minDom.domify)('')); } }); (0, _minDom.classes)(html).add('open'); this._current = { element: element, pad: pad, entries: entries }; this._eventBus.fire('contextPad.open', { current: this._current }); }; ContextPad.prototype.getPad = function (element) { if (this.isOpen()) { return this._current.pad; } var self = this; var overlays = this._overlays; var html = (0, _minDom.domify)('
'); var overlaysConfig = (0, _minDash.assign)({ html: html }, this._overlaysConfig); _minDom.delegate.bind(html, entrySelector, 'click', function (event) { self.trigger('click', event); }); _minDom.delegate.bind(html, entrySelector, 'dragstart', function (event) { self.trigger('dragstart', event); }); // stop propagation of mouse events _minDom.event.bind(html, 'mousedown', function (event) { event.stopPropagation(); }); this._overlayId = overlays.add(element, 'context-pad', overlaysConfig); var pad = overlays.get(this._overlayId); this._eventBus.fire('contextPad.create', { element: element, pad: pad }); return pad; }; /** * Close the context pad */ ContextPad.prototype.close = function () { if (!this.isOpen()) { return; } this._overlays.remove(this._overlayId); this._overlayId = null; this._eventBus.fire('contextPad.close', { current: this._current }); this._current = null; }; /** * Check if pad is open. If element is given, will check * if pad is opened with given element. * * @param {Element} element * @return {Boolean} */ ContextPad.prototype.isOpen = function (element) { return !!this._current && (!element ? true : this._current.element === element); }; // helpers ////////////////////// function addClasses(element, classNames) { var classes = (0, _minDom.classes)(element); var actualClassNames = (0, _minDash.isArray)(classNames) ? classNames : classNames.split(/\s+/g); actualClassNames.forEach(function (cls) { classes.add(cls); }); } },{"min-dash":505,"min-dom":506}],277:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _interactionEvents = require('../interaction-events'); var _interactionEvents2 = _interopRequireDefault(_interactionEvents); var _overlays = require('../overlays'); var _overlays2 = _interopRequireDefault(_overlays); var _ContextPad = require('./ContextPad'); var _ContextPad2 = _interopRequireDefault(_ContextPad); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_interactionEvents2.default, _overlays2.default], contextPad: ['type', _ContextPad2.default] }; },{"../interaction-events":294,"../overlays":339,"./ContextPad":276}],278:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CopyPaste; var _minDash = require('min-dash'); var _Elements = require('../../util/Elements'); var _PositionUtil = require('../../util/PositionUtil'); var _CopyPasteUtil = require('../../util/CopyPasteUtil'); function CopyPaste(eventBus, modeling, elementFactory, rules, clipboard, canvas) { this._eventBus = eventBus; this._modeling = modeling; this._elementFactory = elementFactory; this._rules = rules; this._canvas = canvas; this._clipboard = clipboard; this._descriptors = []; // Element creation priorities: // - 1: Independent shapes // - 2: Attached shapes // - 3: Connections // - 4: labels this.registerDescriptor(function (element, descriptor) { // Base priority descriptor.priority = 1; descriptor.id = element.id; if (element.parent) { descriptor.parent = element.parent.id; } if (element.labelTarget) { // Labels priority descriptor.priority = 4; descriptor.labelTarget = element.labelTarget.id; } if (element.host) { // Attached shapes priority descriptor.priority = 2; descriptor.host = element.host.id; } if (typeof element.x === 'number') { descriptor.x = element.x; descriptor.y = element.y; } if (element.width) { descriptor.width = element.width; descriptor.height = element.height; } if (element.waypoints) { // Connections priority descriptor.priority = 3; descriptor.waypoints = []; (0, _minDash.forEach)(element.waypoints, function (waypoint) { var wp = { x: waypoint.x, y: waypoint.y }; if (waypoint.original) { wp.original = { x: waypoint.original.x, y: waypoint.original.y }; } descriptor.waypoints.push(wp); }); } if (element.source && element.target) { descriptor.source = element.source.id; descriptor.target = element.target.id; } return descriptor; }); } CopyPaste.$inject = ['eventBus', 'modeling', 'elementFactory', 'rules', 'clipboard', 'canvas']; /** * Copy a number of elements. * * @param {djs.model.Base} selectedElements * * @return {Object} the copied tree */ CopyPaste.prototype.copy = function (selectedElements) { var clipboard = this._clipboard, tree, bbox; if (!(0, _minDash.isArray)(selectedElements)) { selectedElements = selectedElements ? [selectedElements] : []; } if (!selectedElements.length) { return; } tree = this.createTree(selectedElements); bbox = this._bbox = (0, _PositionUtil.center)((0, _Elements.getBBox)(tree.allShapes)); // not needed after computing the center position of the copied elements delete tree.allShapes; (0, _minDash.forEach)(tree, function (elements) { (0, _minDash.forEach)(elements, function (element) { var delta, labelTarget; // set label's relative position to their label target if (element.labelTarget) { labelTarget = (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.labelTarget })); // just grab the delta from the first waypoint if (labelTarget.waypoints) { delta = (0, _PositionUtil.delta)(element, labelTarget.waypoints[0]); } else { delta = (0, _PositionUtil.delta)(element, labelTarget); } } else if (element.priority === 3) { // connections have priority 3 delta = []; (0, _minDash.forEach)(element.waypoints, function (waypoint) { var waypointDelta = (0, _PositionUtil.delta)(waypoint, bbox); delta.push(waypointDelta); }); } else { delta = (0, _PositionUtil.delta)(element, bbox); } element.delta = delta; }); }); this._eventBus.fire('elements.copy', { context: { tree: tree } }); // if tree is empty, means that nothing can be or is allowed to be copied if (Object.keys(tree).length === 0) { clipboard.clear(); } else { clipboard.set(tree); } this._eventBus.fire('elements.copied', { context: { tree: tree } }); return tree; }; // Allow pasting under the cursor CopyPaste.prototype.paste = function (context) { var clipboard = this._clipboard, modeling = this._modeling, eventBus = this._eventBus, rules = this._rules; var tree = clipboard.get(), topParent = context.element, position = context.point, newTree, canPaste; if (clipboard.isEmpty()) { return; } newTree = (0, _minDash.reduce)(tree, function (pasteTree, elements, depthStr) { var depth = parseInt(depthStr, 10); if (isNaN(depth)) { return pasteTree; } pasteTree[depth] = elements; return pasteTree; }, {}); canPaste = rules.allowed('elements.paste', { tree: newTree, target: topParent }); if (!canPaste) { eventBus.fire('elements.paste.rejected', { context: { tree: newTree, position: position, target: topParent } }); return; } modeling.pasteElements(newTree, topParent, position); }; CopyPaste.prototype._computeDelta = function (elements, element) { var bbox = this._bbox, delta = {}; // set label's relative position to their label target if (element.labelTarget) { return (0, _PositionUtil.delta)(element, element.labelTarget); } // connections have prority 3 if (element.priority === 3) { delta = []; (0, _minDash.forEach)(element.waypoints, function (waypoint) { var waypointDelta = (0, _PositionUtil.delta)(waypoint, bbox); delta.push(waypointDelta); }); } else { delta = (0, _PositionUtil.delta)(element, bbox); } return delta; }; /** * Checks if the element in question has a relations to other elements. * Possible dependants: connections, labels, attachers * * @param {Array} elements * @param {Object} element * * @return {Boolean} */ CopyPaste.prototype.hasRelations = function (elements, element) { var source, target, labelTarget; if (element.waypoints) { source = (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.source.id })); target = (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.target.id })); if (!source || !target) { return false; } } if (element.labelTarget) { labelTarget = (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.labelTarget.id })); if (!labelTarget) { return false; } } return true; }; CopyPaste.prototype.registerDescriptor = function (descriptor) { if (typeof descriptor !== 'function') { throw new Error('the descriptor must be a function'); } if (this._descriptors.indexOf(descriptor) !== -1) { throw new Error('this descriptor is already registered'); } this._descriptors.push(descriptor); }; CopyPaste.prototype._executeDescriptors = function (data) { if (!data.descriptor) { data.descriptor = {}; } (0, _minDash.forEach)(this._descriptors, function (descriptor) { data.descriptor = descriptor(data.element, data.descriptor); }); return data; }; /** * Creates a tree like structure from an arbitrary collection of elements * * @example * tree: { * 0: [ * { id: 'shape_12da', priority: 1, ... }, * { id: 'shape_01bj', priority: 1, ... }, * { id: 'connection_79fa', source: 'shape_12da', target: 'shape_01bj', priority: 3, ... }, * ], * 1: [ ... ] * }; * * @param {Array} elements * @return {Object} */ CopyPaste.prototype.createTree = function (elements) { var rules = this._rules, self = this; var tree = {}, includedElements = [], _elements; var topLevel = (0, _CopyPasteUtil.getTopLevel)(elements); tree.allShapes = []; function canCopy(collection, element) { return rules.allowed('element.copy', { collection: collection, element: element }); } function includeElement(data) { var idx = (0, _minDash.findIndex)(includedElements, (0, _minDash.matchPattern)({ element: data.element })), element; if (idx !== -1) { element = includedElements[idx]; } else { return includedElements.push(data); } // makes sure that it has the correct depth if (element.depth < data.depth) { includedElements.splice(idx, 1); includedElements.push(data); } } (0, _Elements.eachElement)(topLevel, function (element, i, depth) { var nestedChildren = element.children; // don't add labels directly if (element.labelTarget) { return; } function getNested(lists) { (0, _minDash.forEach)(lists, function (list) { if (list && list.length) { (0, _minDash.forEach)(list, function (elem) { (0, _minDash.forEach)(elem.labels, function (label) { includeElement({ element: label, depth: depth }); }); includeElement({ element: elem, depth: depth }); }); } }); } // fetch element's labels (0, _minDash.forEach)(element.labels, function (label) { includeElement({ element: label, depth: depth }); }); getNested([element.attachers, element.incoming, element.outgoing]); includeElement({ element: element, depth: depth }); if (nestedChildren) { return nestedChildren; } }); includedElements = (0, _minDash.map)(includedElements, function (data) { // this is where other registered descriptors hook in return self._executeDescriptors(data); }); // order the elements to check if the ones dependant on others (by relationship) // can be copied. f.ex: label needs it's label target includedElements = (0, _minDash.sortBy)(includedElements, function (data) { return data.descriptor.priority; }); _elements = (0, _minDash.map)(includedElements, function (data) { return data.element; }); (0, _minDash.forEach)(includedElements, function (data) { var depth = data.depth; if (!self.hasRelations(tree.allShapes, data.element)) { return; } if (!canCopy(_elements, data.element)) { return; } tree.allShapes.push(data.element); // create depth branches if (!tree[depth]) { tree[depth] = []; } tree[depth].push(data.descriptor); }); return tree; }; },{"../../util/CopyPasteUtil":394,"../../util/Elements":396,"../../util/PositionUtil":405,"min-dash":505}],279:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _clipboard = require('../clipboard'); var _clipboard2 = _interopRequireDefault(_clipboard); var _rules = require('../rules'); var _rules2 = _interopRequireDefault(_rules); var _mouseTracking = require('../mouse-tracking'); var _mouseTracking2 = _interopRequireDefault(_mouseTracking); var _CopyPaste = require('./CopyPaste'); var _CopyPaste2 = _interopRequireDefault(_CopyPaste); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_clipboard2.default, _rules2.default, _mouseTracking2.default], __init__: ['copyPaste'], copyPaste: ['type', _CopyPaste2.default] }; },{"../clipboard":273,"../mouse-tracking":331,"../rules":355,"./CopyPaste":278}],280:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Create; var _tinySvg = require('tiny-svg'); var _SvgTransformUtil = require('../../util/SvgTransformUtil'); var LOW_PRIORITY = 750; var MARKER_OK = 'drop-ok', MARKER_NOT_OK = 'drop-not-ok', MARKER_ATTACH = 'attach-ok', MARKER_NEW_PARENT = 'new-parent'; /** * Adds the ability to create new shapes via drag and drop. * * Create must be activated via {@link Create#start}. From that * point on, create will invoke `shape.create` and `shape.attach` * rules to query whether or not creation or attachment on a certain * position is allowed. * * If create or attach is allowed and a source is given, Create it * will invoke `connection.create` rules to query whether a connection * can be drawn between source and new shape. During rule evaluation * the target is not attached yet, however * * hints = { targetParent, targetAttach } * * are passed to the evaluating rules. * * * ## Rule Return Values * * Return values interpreted from `shape.create`: * * * `true`: create is allowed * * `false`: create is disallowed * * `null`: create is not allowed but should be ignored visually * * Return values interpreted from `shape.attach`: * * * `true`: attach is allowed * * `Any`: attach is allowed with the constraints * * `false`: attach is disallowed * * Return values interpreted from `connection.create`: * * * `true`: connection can be created * * `Any`: connection with the given attributes can be created * * `false`: connection can't be created * * * @param {EventBus} eventBus * @param {Dragging} dragging * @param {Rules} rules * @param {Modeling} modeling * @param {Canvas} canvas * @param {Styles} styles * @param {GraphicsFactory} graphicsFactory */ function Create(eventBus, dragging, rules, modeling, canvas, styles, graphicsFactory) { // rules function canCreate(shape, target, source, position) { if (!target) { return false; } var ctx = { source: source, shape: shape, target: target, position: position }; var create, attach, connect; attach = rules.allowed('shape.attach', ctx); if (!attach) { create = rules.allowed('shape.create', ctx); } if (create || attach) { connect = source && rules.allowed('connection.create', { source: source, target: shape, hints: { targetParent: target, targetAttach: attach } }); } if (create || attach) { return { attach: attach, connect: connect }; } return false; } /** set drop marker on an element */ function setMarker(element, marker) { [MARKER_ATTACH, MARKER_OK, MARKER_NOT_OK, MARKER_NEW_PARENT].forEach(function (m) { if (m === marker) { canvas.addMarker(element, m); } else { canvas.removeMarker(element, m); } }); } // visual helpers function createVisual(shape) { var group, preview, visual; group = (0, _tinySvg.create)('g'); (0, _tinySvg.attr)(group, styles.cls('djs-drag-group', ['no-events'])); (0, _tinySvg.append)(canvas.getDefaultLayer(), group); preview = (0, _tinySvg.create)('g'); (0, _tinySvg.classes)(preview).add('djs-dragger'); (0, _tinySvg.append)(group, preview); (0, _SvgTransformUtil.translate)(preview, shape.width / -2, shape.height / -2); var visualGroup = (0, _tinySvg.create)('g'); (0, _tinySvg.classes)(visualGroup).add('djs-visual'); (0, _tinySvg.append)(preview, visualGroup); visual = visualGroup; // hijack renderer to draw preview graphicsFactory.drawShape(visual, shape); return group; } // event handlers eventBus.on('create.move', function (event) { var context = event.context, hover = event.hover, shape = context.shape, source = context.source, canExecute; var position = { x: event.x, y: event.y }; canExecute = context.canExecute = hover && canCreate(shape, hover, source, position); // ignore hover visually if canExecute is null if (hover && canExecute !== null) { context.target = hover; if (canExecute && canExecute.attach) { setMarker(hover, MARKER_ATTACH); } else { setMarker(hover, canExecute ? MARKER_NEW_PARENT : MARKER_NOT_OK); } } }); eventBus.on('create.move', LOW_PRIORITY, function (event) { var context = event.context, shape = context.shape, visual = context.visual; // lazy init drag visual once we received the first real // drag move event (this allows us to get the proper canvas local coordinates) if (!visual) { visual = context.visual = createVisual(shape); } (0, _SvgTransformUtil.translate)(visual, event.x, event.y); }); eventBus.on(['create.end', 'create.out', 'create.cleanup'], function (event) { var context = event.context, target = context.target; if (target) { setMarker(target, null); } }); eventBus.on('create.end', function (event) { var context = event.context, source = context.source, shape = context.shape, target = context.target, canExecute = context.canExecute, attach = canExecute && canExecute.attach, connect = canExecute && canExecute.connect, position = { x: event.x, y: event.y }; if (!canExecute) { return false; } if (connect) { // invoke append if connect is set via rules shape = modeling.appendShape(source, shape, position, target, { attach: attach, connection: connect === true ? {} : connect }); } else { // invoke create, if connect is not set shape = modeling.createShape(shape, position, target, { attach: attach }); } // make sure we provide the actual attached // shape with the context so that selection and // other components can use it right after the create // operation ends context.shape = shape; }); eventBus.on('create.cleanup', function (event) { var context = event.context; if (context.visual) { (0, _tinySvg.remove)(context.visual); } }); // API this.start = function (event, shape, source) { dragging.init(event, 'create', { cursor: 'grabbing', autoActivate: true, data: { shape: shape, context: { shape: shape, source: source } } }); }; } Create.$inject = ['eventBus', 'dragging', 'rules', 'modeling', 'canvas', 'styles', 'graphicsFactory']; },{"../../util/SvgTransformUtil":408,"tiny-svg":535}],281:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _dragging = require('../dragging'); var _dragging2 = _interopRequireDefault(_dragging); var _selection = require('../selection'); var _selection2 = _interopRequireDefault(_selection); var _rules = require('../rules'); var _rules2 = _interopRequireDefault(_rules); var _Create = require('./Create'); var _Create2 = _interopRequireDefault(_Create); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_dragging2.default, _selection2.default, _rules2.default], create: ['type', _Create2.default] }; },{"../dragging":286,"../rules":355,"../selection":361,"./Create":280}],282:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DistributeElements; var _minDash = require('min-dash'); var AXIS_DIMENSIONS = { horizontal: ['x', 'width'], vertical: ['y', 'height'] }; var THRESHOLD = 5; /** * Groups and filters elements and then trigger even distribution. */ function DistributeElements(modeling) { this._modeling = modeling; this._filters = []; // register filter for filtering big elements this.registerFilter(function (elements, axis, dimension) { var elementsSize = 0, numOfShapes = 0, avgDimension; (0, _minDash.forEach)(elements, function (element) { if (element.waypoints || element.labelTarget) { return; } elementsSize += element[dimension]; numOfShapes += 1; }); avgDimension = Math.round(elementsSize / numOfShapes); return (0, _minDash.filter)(elements, function (element) { return element[dimension] < avgDimension + 50; }); }); } DistributeElements.$inject = ['modeling']; /** * Registers filter functions that allow external parties to filter * out certain elements. * * @param {Function} filterFn */ DistributeElements.prototype.registerFilter = function (filterFn) { if (typeof filterFn !== 'function') { throw new Error('the filter has to be a function'); } this._filters.push(filterFn); }; /** * Distributes the elements with a given orientation * * @param {Array} elements [description] * @param {String} orientation [description] */ DistributeElements.prototype.trigger = function (elements, orientation) { var modeling = this._modeling; var groups, distributableElements; if (elements.length < 3) { return; } this._setOrientation(orientation); distributableElements = this._filterElements(elements); groups = this._createGroups(distributableElements); // nothing to distribute if (groups.length <= 2) { return; } modeling.distributeElements(groups, this._axis, this._dimension); return groups; }; /** * Filters the elements with provided filters by external parties * * @param {Array[Elements]} elements * * @return {Array[Elements]} */ DistributeElements.prototype._filterElements = function (elements) { var filters = this._filters, axis = this._axis, dimension = this._dimension, distributableElements = [].concat(elements); if (!filters.length) { return elements; } (0, _minDash.forEach)(filters, function (filterFn) { distributableElements = filterFn(distributableElements, axis, dimension); }); return distributableElements; }; /** * Create range (min, max) groups. Also tries to group elements * together that share the same range. * * @example * var distributableElements = [ * { * range: { * min: 100, * max: 200 * }, * elements: [ { id: 'shape1', .. }] * } * ] * * @param {Array} elements * * @return {Array[Objects]} */ DistributeElements.prototype._createGroups = function (elements) { var rangeGroups = [], self = this, axis = this._axis, dimension = this._dimension; if (!axis) { throw new Error('must have a defined "axis" and "dimension"'); } // sort by 'left->right' or 'top->bottom' var sortedElements = (0, _minDash.sortBy)(elements, axis); (0, _minDash.forEach)(sortedElements, function (element, idx) { var elementRange = self._findRange(element, axis, dimension), range; var previous = rangeGroups[rangeGroups.length - 1]; if (previous && self._hasIntersection(previous.range, elementRange)) { rangeGroups[rangeGroups.length - 1].elements.push(element); } else { range = { range: elementRange, elements: [element] }; rangeGroups.push(range); } }); return rangeGroups; }; /** * Maps a direction to the according axis and dimension * * @param {String} direction 'horizontal' or 'vertical' */ DistributeElements.prototype._setOrientation = function (direction) { var orientation = AXIS_DIMENSIONS[direction]; this._axis = orientation[0]; this._dimension = orientation[1]; }; /** * Checks if the two ranges intercept each other * * @param {Object} rangeA {min, max} * @param {Object} rangeB {min, max} * * @return {Boolean} */ DistributeElements.prototype._hasIntersection = function (rangeA, rangeB) { return Math.max(rangeA.min, rangeA.max) >= Math.min(rangeB.min, rangeB.max) && Math.min(rangeA.min, rangeA.max) <= Math.max(rangeB.min, rangeB.max); }; /** * Returns the min and max values for an element * * @param {[type]} element [description] * @param {[type]} axis [description] * @param {[type]} dimension [description] * * @return {[type]} [description] */ DistributeElements.prototype._findRange = function (element) { var axis = element[this._axis], dimension = element[this._dimension]; return { min: axis + THRESHOLD, max: axis + dimension - THRESHOLD }; }; },{"min-dash":505}],283:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _DistributeElements = require('./DistributeElements'); var _DistributeElements2 = _interopRequireDefault(_DistributeElements); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['distributeElements'], distributeElements: ['type', _DistributeElements2.default] }; },{"./DistributeElements":282}],284:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Dragging; var _minDash = require('min-dash'); var _minDom = require('min-dom'); var _Event = require('../../util/Event'); var _Cursor = require('../../util/Cursor'); var _ClickTrap = require('../../util/ClickTrap'); var _PositionUtil = require('../../util/PositionUtil'); /* global TouchEvent */ var round = Math.round; var DRAG_ACTIVE_CLS = 'djs-drag-active'; function preventDefault(event) { event.preventDefault(); } function isTouchEvent(event) { // check for TouchEvent being available first // (i.e. not available on desktop Firefox) return typeof TouchEvent !== 'undefined' && event instanceof TouchEvent; } function getLength(point) { return Math.sqrt(Math.pow(point.x, 2) + Math.pow(point.y, 2)); } /** * A helper that fires canvas localized drag events and realizes * the general "drag-and-drop" look and feel. * * Calling {@link Dragging#activate} activates dragging on a canvas. * * It provides the following: * * * emits life cycle events, namespaced with a prefix assigned * during dragging activation * * sets and restores the cursor * * sets and restores the selection * * ensures there can be only one drag operation active at a time * * Dragging may be canceled manually by calling {@link Dragging#cancel} * or by pressing ESC. * * * ## Life-cycle events * * Dragging can be in three different states, off, initialized * and active. * * (1) off: no dragging operation is in progress * (2) initialized: a new drag operation got initialized but not yet * started (i.e. because of no initial move) * (3) started: dragging is in progress * * Eventually dragging will be off again after a drag operation has * been ended or canceled via user click or ESC key press. * * To indicate transitions between these states dragging emits generic * life-cycle events with the `drag.` prefix _and_ events namespaced * to a prefix choosen by a user during drag initialization. * * The following events are emitted (appropriately prefixed) via * the {@link EventBus}. * * * `init` * * `start` * * `move` * * `end` * * `ended` (dragging already in off state) * * `cancel` (only if previously started) * * `canceled` (dragging already in off state, only if previously started) * * `cleanup` * * * @example * * function MyDragComponent(eventBus, dragging) { * * eventBus.on('mydrag.start', function(event) { * console.log('yes, we start dragging'); * }); * * eventBus.on('mydrag.move', function(event) { * console.log('canvas local coordinates', event.x, event.y, event.dx, event.dy); * * // local drag data is passed with the event * event.context.foo; // "BAR" * * // the original mouse event, too * event.originalEvent; // MouseEvent(...) * }); * * eventBus.on('element.click', function(event) { * dragging.init(event, 'mydrag', { * cursor: 'grabbing', * data: { * context: { * foo: "BAR" * } * } * }); * }); * } */ function Dragging(eventBus, canvas, selection) { var defaultOptions = { threshold: 5, trapClick: true }; // the currently active drag operation // dragging is active as soon as this context exists. // // it is visually _active_ only when a context.active flag is set to true. var context; /* convert a global event into local coordinates */ function toLocalPoint(globalPosition) { var viewbox = canvas.viewbox(); var clientRect = canvas._container.getBoundingClientRect(); return { x: viewbox.x + (globalPosition.x - clientRect.left) / viewbox.scale, y: viewbox.y + (globalPosition.y - clientRect.top) / viewbox.scale }; } // helpers function fire(type, dragContext) { dragContext = dragContext || context; var event = eventBus.createEvent((0, _minDash.assign)({}, dragContext.payload, dragContext.data, { isTouch: dragContext.isTouch })); // default integration if (eventBus.fire('drag.' + type, event) === false) { return false; } return eventBus.fire(dragContext.prefix + '.' + type, event); } // event listeners function move(event, activate) { var payload = context.payload, displacement = context.displacement; var globalStart = context.globalStart, globalCurrent = (0, _Event.toPoint)(event), globalDelta = (0, _PositionUtil.delta)(globalCurrent, globalStart); var localStart = context.localStart, localCurrent = toLocalPoint(globalCurrent), localDelta = (0, _PositionUtil.delta)(localCurrent, localStart); // activate context explicitly or once threshold is reached if (!context.active && (activate || getLength(globalDelta) > context.threshold)) { // fire start event with original // starting coordinates (0, _minDash.assign)(payload, { x: round(localStart.x + displacement.x), y: round(localStart.y + displacement.y), dx: 0, dy: 0 }, { originalEvent: event }); if (false === fire('start')) { return cancel(); } context.active = true; // unset selection and remember old selection // the previous (old) selection will always passed // with the event via the event.previousSelection property if (!context.keepSelection) { payload.previousSelection = selection.get(); selection.select(null); } // allow custom cursor if (context.cursor) { (0, _Cursor.set)(context.cursor); } // indicate dragging via marker on root element canvas.addMarker(canvas.getRootElement(), DRAG_ACTIVE_CLS); } (0, _Event.stopPropagation)(event); if (context.active) { // update payload with actual coordinates (0, _minDash.assign)(payload, { x: round(localCurrent.x + displacement.x), y: round(localCurrent.y + displacement.y), dx: round(localDelta.x), dy: round(localDelta.y) }, { originalEvent: event }); // emit move event fire('move'); } } function end(event) { var previousContext, returnValue = true; if (context.active) { if (event) { context.payload.originalEvent = event; // suppress original event (click, ...) // because we just ended a drag operation (0, _Event.stopPropagation)(event); } // implementations may stop restoring the // original state (selections, ...) by preventing the // end events default action returnValue = fire('end'); } if (returnValue === false) { fire('rejected'); } previousContext = cleanup(returnValue !== true); // last event to be fired when all drag operations are done // at this point in time no drag operation is in progress anymore fire('ended', previousContext); } // cancel active drag operation if the user presses // the ESC key on the keyboard function checkCancel(event) { if (event.which === 27) { preventDefault(event); cancel(); } } // prevent ghost click that might occur after a finished // drag and drop session function trapClickAndEnd(event) { var untrap; // trap the click in case we are part of an active // drag operation. This will effectively prevent // the ghost click that cannot be canceled otherwise. if (context.active) { untrap = (0, _ClickTrap.install)(eventBus); // remove trap after minimal delay setTimeout(untrap, 400); // prevent default action (click) preventDefault(event); } end(event); } function trapTouch(event) { move(event); } // update the drag events hover (djs.model.Base) and hoverGfx (Snap) // properties during hover and out and fire {prefix}.hover and {prefix}.out properties // respectively function hover(event) { var payload = context.payload; payload.hoverGfx = event.gfx; payload.hover = event.element; fire('hover'); } function out(event) { fire('out'); var payload = context.payload; payload.hoverGfx = null; payload.hover = null; } // life-cycle methods function cancel(restore) { var previousContext; if (!context) { return; } var wasActive = context.active; if (wasActive) { fire('cancel'); } previousContext = cleanup(restore); if (wasActive) { // last event to be fired when all drag operations are done // at this point in time no drag operation is in progress anymore fire('canceled', previousContext); } } function cleanup(restore) { var previousContext, endDrag; fire('cleanup'); // reset cursor (0, _Cursor.unset)(); if (context.trapClick) { endDrag = trapClickAndEnd; } else { endDrag = end; } // reset dom listeners _minDom.event.unbind(document, 'mousemove', move); _minDom.event.unbind(document, 'dragstart', preventDefault); _minDom.event.unbind(document, 'selectstart', preventDefault); _minDom.event.unbind(document, 'mousedown', endDrag, true); _minDom.event.unbind(document, 'mouseup', endDrag, true); _minDom.event.unbind(document, 'keyup', checkCancel); _minDom.event.unbind(document, 'touchstart', trapTouch, true); _minDom.event.unbind(document, 'touchcancel', cancel, true); _minDom.event.unbind(document, 'touchmove', move, true); _minDom.event.unbind(document, 'touchend', end, true); eventBus.off('element.hover', hover); eventBus.off('element.out', out); // remove drag marker on root element canvas.removeMarker(canvas.getRootElement(), DRAG_ACTIVE_CLS); // restore selection, unless it has changed var previousSelection = context.payload.previousSelection; if (restore !== false && previousSelection && !selection.get().length) { selection.select(previousSelection); } previousContext = context; context = null; return previousContext; } /** * Initialize a drag operation. * * If `localPosition` is given, drag events will be emitted * relative to it. * * @param {MouseEvent|TouchEvent} [event] * @param {Point} [localPosition] actual diagram local position this drag operation should start at * @param {String} prefix * @param {Object} [options] */ function init(event, relativeTo, prefix, options) { // only one drag operation may be active, at a time if (context) { cancel(false); } if (typeof relativeTo === 'string') { options = prefix; prefix = relativeTo; relativeTo = null; } options = (0, _minDash.assign)({}, defaultOptions, options || {}); var data = options.data || {}, originalEvent, globalStart, localStart, endDrag, isTouch; if (options.trapClick) { endDrag = trapClickAndEnd; } else { endDrag = end; } if (event) { originalEvent = (0, _Event.getOriginal)(event) || event; globalStart = (0, _Event.toPoint)(event); (0, _Event.stopPropagation)(event); // prevent default browser dragging behavior if (originalEvent.type === 'dragstart') { preventDefault(originalEvent); } } else { originalEvent = null; globalStart = { x: 0, y: 0 }; } localStart = toLocalPoint(globalStart); if (!relativeTo) { relativeTo = localStart; } isTouch = isTouchEvent(originalEvent); context = (0, _minDash.assign)({ prefix: prefix, data: data, payload: {}, globalStart: globalStart, displacement: (0, _PositionUtil.delta)(relativeTo, localStart), localStart: localStart, isTouch: isTouch }, options); // skip dom registration if trigger // is set to manual (during testing) if (!options.manual) { // add dom listeners if (isTouch) { _minDom.event.bind(document, 'touchstart', trapTouch, true); _minDom.event.bind(document, 'touchcancel', cancel, true); _minDom.event.bind(document, 'touchmove', move, true); _minDom.event.bind(document, 'touchend', end, true); } else { // assume we use the mouse to interact per default _minDom.event.bind(document, 'mousemove', move); // prevent default browser drag and text selection behavior _minDom.event.bind(document, 'dragstart', preventDefault); _minDom.event.bind(document, 'selectstart', preventDefault); _minDom.event.bind(document, 'mousedown', endDrag, true); _minDom.event.bind(document, 'mouseup', endDrag, true); } _minDom.event.bind(document, 'keyup', checkCancel); eventBus.on('element.hover', hover); eventBus.on('element.out', out); } fire('init'); if (options.autoActivate) { move(event, true); } } // cancel on diagram destruction eventBus.on('diagram.destroy', cancel); // API this.init = init; this.move = move; this.hover = hover; this.out = out; this.end = end; this.cancel = cancel; // for introspection this.context = function () { return context; }; this.setOptions = function (options) { (0, _minDash.assign)(defaultOptions, options); }; } Dragging.$inject = ['eventBus', 'canvas', 'selection']; },{"../../util/ClickTrap":392,"../../util/Cursor":395,"../../util/Event":397,"../../util/PositionUtil":405,"min-dash":505,"min-dom":506}],285:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = HoverFix; var _minDom = require('min-dom'); var _Event = require('../../util/Event'); function getGfx(target) { var node = (0, _minDom.closest)(target, 'svg, .djs-element', true); return node; } /** * Browsers may swallow the hover event if users are to * fast with the mouse. * * @see http://stackoverflow.com/questions/7448468/why-cant-i-reliably-capture-a-mouseout-event * * The fix implemented in this component ensure that we * have a hover state after a successive drag.move event. * * @param {EventBus} eventBus * @param {Dragging} dragging * @param {ElementRegistry} elementRegistry */ function HoverFix(eventBus, dragging, elementRegistry) { var self = this; // we wait for a specific sequence of events before // emitting a fake drag.hover event. // // Event Sequence: // // drag.start // drag.move // drag.move >> ensure we are hovering // eventBus.on('drag.start', function (event) { eventBus.once('drag.move', function () { eventBus.once('drag.move', function (event) { self.ensureHover(event); }); }); }); /** * Make sure we are god damn hovering! * * @param {Event} dragging event */ this.ensureHover = function (event) { if (event.hover) { return; } var originalEvent = event.originalEvent, position, target, element, gfx; if (!(originalEvent instanceof MouseEvent)) { return; } position = (0, _Event.toPoint)(originalEvent); // damn expensive operation, ouch! target = document.elementFromPoint(position.x, position.y); gfx = getGfx(target); if (gfx) { element = elementRegistry.get(gfx); dragging.hover({ element: element, gfx: gfx }); } }; } HoverFix.$inject = ['eventBus', 'dragging', 'elementRegistry']; },{"../../util/Event":397,"min-dom":506}],286:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _selection = require('../selection'); var _selection2 = _interopRequireDefault(_selection); var _Dragging = require('./Dragging'); var _Dragging2 = _interopRequireDefault(_Dragging); var _HoverFix = require('./HoverFix'); var _HoverFix2 = _interopRequireDefault(_HoverFix); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['hoverFix'], __depends__: [_selection2.default], dragging: ['type', _Dragging2.default], hoverFix: ['type', _HoverFix2.default] }; },{"../selection":361,"./Dragging":284,"./HoverFix":285}],287:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = EditorActions; var _minDash = require('min-dash'); var NOT_REGISTERED_ERROR = 'is not a registered action', IS_REGISTERED_ERROR = 'is already registered'; /** * An interface that provides access to modeling actions by decoupling * the one who requests the action to be triggered and the trigger itself. * * It's possible to add new actions by registering them with ´registerAction´ * and likewise unregister existing ones with ´unregisterAction´. * * * ## Life-Cycle and configuration * * The editor actions will wait for diagram initialization before * registering default actions _and_ firing an `editorActions.init` event. * * Interested parties may listen to the `editorActions.init` event with * low priority to check, which actions got registered. Other components * may use the event to register their own actions via `registerAction`. * * @param {EventBus} eventBus * @param {Injector} injector */ function EditorActions(eventBus, injector) { // initialize actions this._actions = {}; var self = this; eventBus.on('diagram.init', function () { // all diagram modules got loaded; check which ones // are available and register the respective default actions self._registerDefaultActions(injector); // ask interested parties to register available editor // actions on diagram initialization eventBus.fire('editorActions.init', { editorActions: self }); }); } EditorActions.$inject = ['eventBus', 'injector']; /** * Register default actions. * * @param {Injector} injector */ EditorActions.prototype._registerDefaultActions = function (injector) { // (1) retrieve optional components to integrate with var commandStack = injector.get('commandStack', false); var modeling = injector.get('modeling', false); var selection = injector.get('selection', false); var zoomScroll = injector.get('zoomScroll', false); var copyPaste = injector.get('copyPaste', false); var canvas = injector.get('canvas', false); var rules = injector.get('rules', false); var mouseTracking = injector.get('mouseTracking', false); var keyboardMove = injector.get('keyboardMove', false); var keyboardMoveSelection = injector.get('keyboardMoveSelection', false); // (2) check components and register actions if (commandStack) { this.register('undo', function () { commandStack.undo(); }); this.register('redo', function () { commandStack.redo(); }); } if (copyPaste && selection) { this.register('copy', function () { var selectedElements = selection.get(); copyPaste.copy(selectedElements); }); } if (mouseTracking && copyPaste) { this.register('paste', function () { var context = mouseTracking.getHoverContext(); copyPaste.paste(context); }); } if (zoomScroll) { this.register('stepZoom', function (opts) { zoomScroll.stepZoom(opts.value); }); } if (canvas) { this.register('zoom', function (opts) { canvas.zoom(opts.value); }); } if (modeling && selection && rules) { this.register('removeSelection', function () { var selectedElements = selection.get(); if (!selectedElements.length) { return; } var allowed = rules.allowed('elements.delete', { elements: selectedElements }), removableElements; if (allowed === false) { return; } else if ((0, _minDash.isArray)(allowed)) { removableElements = allowed; } else { removableElements = selectedElements; } if (removableElements.length) { modeling.removeElements(removableElements.slice()); } }); } if (keyboardMove) { this.register('moveCanvas', function (opts) { keyboardMove.moveCanvas(opts); }); } if (keyboardMoveSelection) { this.register('moveSelection', function (opts) { keyboardMoveSelection.moveSelection(opts.direction, opts.accelerated); }); } }; /** * Triggers a registered action * * @param {String} action * @param {Object} opts * * @return {Unknown} Returns what the registered listener returns */ EditorActions.prototype.trigger = function (action, opts) { if (!this._actions[action]) { throw error(action, NOT_REGISTERED_ERROR); } return this._actions[action](opts); }; /** * Registers a collections of actions. * The key of the object will be the name of the action. * * @example * ´´´ * var actions = { * spaceTool: function() { * spaceTool.activateSelection(); * }, * lassoTool: function() { * lassoTool.activateSelection(); * } * ]; * * editorActions.register(actions); * * editorActions.isRegistered('spaceTool'); // true * ´´´ * * @param {Object} actions */ EditorActions.prototype.register = function (actions, listener) { var self = this; if (typeof actions === 'string') { return this._registerAction(actions, listener); } (0, _minDash.forEach)(actions, function (listener, action) { self._registerAction(action, listener); }); }; /** * Registers a listener to an action key * * @param {String} action * @param {Function} listener */ EditorActions.prototype._registerAction = function (action, listener) { if (this.isRegistered(action)) { throw error(action, IS_REGISTERED_ERROR); } this._actions[action] = listener; }; /** * Unregister an existing action * * @param {String} action */ EditorActions.prototype.unregister = function (action) { if (!this.isRegistered(action)) { throw error(action, NOT_REGISTERED_ERROR); } this._actions[action] = undefined; }; /** * Returns the number of actions that are currently registered * * @return {Number} */ EditorActions.prototype.getActions = function () { return Object.keys(this._actions); }; /** * Checks wether the given action is registered * * @param {String} action * * @return {Boolean} */ EditorActions.prototype.isRegistered = function (action) { return !!this._actions[action]; }; function error(action, message) { return new Error(action + ' ' + message); } },{"min-dash":505}],288:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _EditorActions = require('./EditorActions'); var _EditorActions2 = _interopRequireDefault(_EditorActions); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['editorActions'], editorActions: ['type', _EditorActions2.default] }; },{"./EditorActions":287}],289:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = GlobalConnect; var MARKER_OK = 'connect-ok', MARKER_NOT_OK = 'connect-not-ok'; /** * @class * @constructor * * @param {EventBus} eventBus * @param {Dragging} dragging * @param {Connect} connect * @param {Canvas} canvas * @param {ToolManager} toolManager * @param {Rules} rules */ function GlobalConnect(eventBus, dragging, connect, canvas, toolManager, rules) { var self = this; this._dragging = dragging; this._rules = rules; toolManager.registerTool('global-connect', { tool: 'global-connect', dragging: 'global-connect.drag' }); eventBus.on('global-connect.hover', function (event) { var context = event.context, startTarget = event.hover; var canStartConnect = context.canStartConnect = self.canStartConnect(startTarget); // simply ignore hover if (canStartConnect === null) { return; } context.startTarget = startTarget; canvas.addMarker(startTarget, canStartConnect ? MARKER_OK : MARKER_NOT_OK); }); eventBus.on(['global-connect.out', 'global-connect.cleanup'], function (event) { var startTarget = event.context.startTarget, canStartConnect = event.context.canStartConnect; if (startTarget) { canvas.removeMarker(startTarget, canStartConnect ? MARKER_OK : MARKER_NOT_OK); } }); eventBus.on(['global-connect.ended'], function (event) { var context = event.context, startTarget = context.startTarget, startPosition = { x: event.x, y: event.y }; var canStartConnect = self.canStartConnect(startTarget); if (!canStartConnect) { return; } eventBus.once('element.out', function () { eventBus.once(['connect.ended', 'connect.canceled'], function () { eventBus.fire('global-connect.drag.ended'); }); connect.start(null, startTarget, startPosition); }); return false; }); } GlobalConnect.$inject = ['eventBus', 'dragging', 'connect', 'canvas', 'toolManager', 'rules']; /** * Initiates tool activity. */ GlobalConnect.prototype.start = function (event) { this._dragging.init(event, 'global-connect', { trapClick: false, data: { context: {} } }); }; GlobalConnect.prototype.toggle = function () { if (this.isActive()) { this._dragging.cancel(); } else { this.start(); } }; GlobalConnect.prototype.isActive = function () { var context = this._dragging.context(); return context && /^global-connect/.test(context.prefix); }; /** * Check if source shape can initiate connection. * * @param {Shape} startTarget * @return {Boolean} */ GlobalConnect.prototype.canStartConnect = function (startTarget) { return this._rules.allowed('connection.start', { source: startTarget }); }; },{}],290:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _connect = require('../connect'); var _connect2 = _interopRequireDefault(_connect); var _rules = require('../rules'); var _rules2 = _interopRequireDefault(_rules); var _dragging = require('../dragging'); var _dragging2 = _interopRequireDefault(_dragging); var _toolManager = require('../tool-manager'); var _toolManager2 = _interopRequireDefault(_toolManager); var _GlobalConnect = require('./GlobalConnect'); var _GlobalConnect2 = _interopRequireDefault(_GlobalConnect); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_connect2.default, _rules2.default, _dragging2.default, _toolManager2.default], globalConnect: ['type', _GlobalConnect2.default] }; },{"../connect":275,"../dragging":286,"../rules":355,"../tool-manager":370,"./GlobalConnect":289}],291:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; exports.default = HandTool; var _Mouse = require('../../util/Mouse'); var HIGH_PRIORITY = 1500; var HAND_CURSOR = 'grab'; function HandTool(eventBus, canvas, dragging, toolManager) { this._dragging = dragging; toolManager.registerTool('hand', { tool: 'hand', dragging: 'hand.move' }); eventBus.on('element.mousedown', HIGH_PRIORITY, function (event) { if ((0, _Mouse.hasPrimaryModifier)(event)) { this.activateMove(event.originalEvent); return false; } }, this); eventBus.on('hand.end', function (event) { var target = event.originalEvent.target; // only reactive on diagram click // on some occasions, event.hover is not set and we have to check if the target is an svg if (!event.hover && !(target instanceof SVGElement)) { return false; } eventBus.once('hand.ended', function () { this.activateMove(event.originalEvent, { reactivate: true }); }, this); }, this); eventBus.on('hand.move.move', function (event) { var scale = canvas.viewbox().scale; canvas.scroll({ dx: event.dx * scale, dy: event.dy * scale }); }); eventBus.on('hand.move.end', function (event) { var context = event.context, reactivate = context.reactivate; // Don't reactivate if the user is using the keyboard keybinding if (!(0, _Mouse.hasPrimaryModifier)(event) && reactivate) { eventBus.once('hand.move.ended', function (event) { this.activateHand(event.originalEvent, true, true); }, this); } return false; }, this); } HandTool.$inject = ['eventBus', 'canvas', 'dragging', 'toolManager']; HandTool.prototype.activateMove = function (event, autoActivate, context) { if ((typeof autoActivate === 'undefined' ? 'undefined' : _typeof(autoActivate)) === 'object') { context = autoActivate; autoActivate = false; } this._dragging.init(event, 'hand.move', { autoActivate: autoActivate, cursor: HAND_CURSOR, data: { context: context || {} } }); }; HandTool.prototype.activateHand = function (event, autoActivate, reactivate) { this._dragging.init(event, 'hand', { trapClick: false, autoActivate: autoActivate, cursor: HAND_CURSOR, data: { context: { reactivate: reactivate } } }); }; HandTool.prototype.toggle = function () { if (this.isActive()) { this._dragging.cancel(); } else { this.activateHand(); } }; HandTool.prototype.isActive = function () { var context = this._dragging.context(); return context && /^hand/.test(context.prefix); }; },{"../../util/Mouse":403}],292:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _toolManager = require('../tool-manager'); var _toolManager2 = _interopRequireDefault(_toolManager); var _HandTool = require('./HandTool'); var _HandTool2 = _interopRequireDefault(_HandTool); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_toolManager2.default], __init__: ['handTool'], handTool: ['type', _HandTool2.default] }; },{"../tool-manager":370,"./HandTool":291}],293:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = InteractionEvents; var _minDash = require('min-dash'); var _minDom = require('min-dom'); var _Mouse = require('../../util/Mouse'); var _tinySvg = require('tiny-svg'); var _RenderUtil = require('../../util/RenderUtil'); function allowAll(e) { return true; } var LOW_PRIORITY = 500; /** * A plugin that provides interaction events for diagram elements. * * It emits the following events: * * * element.hover * * element.out * * element.click * * element.dblclick * * element.mousedown * * element.contextmenu * * Each event is a tuple { element, gfx, originalEvent }. * * Canceling the event via Event#preventDefault() * prevents the original DOM operation. * * @param {EventBus} eventBus */ function InteractionEvents(eventBus, elementRegistry, styles) { var HIT_STYLE = styles.cls('djs-hit', ['no-fill', 'no-border'], { stroke: 'white', strokeWidth: 15 }); /** * Fire an interaction event. * * @param {String} type local event name, e.g. element.click. * @param {DOMEvent} event native event * @param {djs.model.Base} [element] the diagram element to emit the event on; * defaults to the event target */ function fire(type, event, element) { if (isIgnored(type, event)) { return; } var target, gfx, returnValue; if (!element) { target = event.delegateTarget || event.target; if (target) { gfx = target; element = elementRegistry.get(gfx); } } else { gfx = elementRegistry.getGraphics(element); } if (!gfx || !element) { return; } returnValue = eventBus.fire(type, { element: element, gfx: gfx, originalEvent: event }); if (returnValue === false) { event.stopPropagation(); event.preventDefault(); } } // TODO(nikku): document this var handlers = {}; function mouseHandler(localEventName) { return handlers[localEventName]; } function isIgnored(localEventName, event) { var filter = ignoredFilters[localEventName] || _Mouse.isPrimaryButton; // only react on left mouse button interactions // except for interaction events that are enabled // for secundary mouse button return !filter(event); } var bindings = { mouseover: 'element.hover', mouseout: 'element.out', click: 'element.click', dblclick: 'element.dblclick', mousedown: 'element.mousedown', mouseup: 'element.mouseup', contextmenu: 'element.contextmenu' }; var ignoredFilters = { 'element.contextmenu': allowAll }; // manual event trigger /** * Trigger an interaction event (based on a native dom event) * on the target shape or connection. * * @param {String} eventName the name of the triggered DOM event * @param {MouseEvent} event * @param {djs.model.Base} targetElement */ function triggerMouseEvent(eventName, event, targetElement) { // i.e. element.mousedown... var localEventName = bindings[eventName]; if (!localEventName) { throw new Error('unmapped DOM event name <' + eventName + '>'); } return fire(localEventName, event, targetElement); } var elementSelector = 'svg, .djs-element'; // event registration function registerEvent(node, event, localEvent, ignoredFilter) { var handler = handlers[localEvent] = function (event) { fire(localEvent, event); }; if (ignoredFilter) { ignoredFilters[localEvent] = ignoredFilter; } handler.$delegate = _minDom.delegate.bind(node, elementSelector, event, handler); } function unregisterEvent(node, event, localEvent) { var handler = mouseHandler(localEvent); if (!handler) { return; } _minDom.delegate.unbind(node, event, handler.$delegate); } function registerEvents(svg) { (0, _minDash.forEach)(bindings, function (val, key) { registerEvent(svg, key, val); }); } function unregisterEvents(svg) { (0, _minDash.forEach)(bindings, function (val, key) { unregisterEvent(svg, key, val); }); } eventBus.on('canvas.destroy', function (event) { unregisterEvents(event.svg); }); eventBus.on('canvas.init', function (event) { registerEvents(event.svg); }); eventBus.on(['shape.added', 'connection.added'], function (event) { var element = event.element, gfx = event.gfx, hit; if (element.waypoints) { hit = (0, _RenderUtil.createLine)(element.waypoints); } else { hit = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(hit, { x: 0, y: 0, width: element.width, height: element.height }); } (0, _tinySvg.attr)(hit, HIT_STYLE); (0, _tinySvg.append)(gfx, hit); }); // Update djs-hit on change. // A low priortity is necessary, because djs-hit of labels has to be updated // after the label bounds have been updated in the renderer. eventBus.on('shape.changed', LOW_PRIORITY, function (event) { var element = event.element, gfx = event.gfx, hit = (0, _minDom.query)('.djs-hit', gfx); (0, _tinySvg.attr)(hit, { width: element.width, height: element.height }); }); eventBus.on('connection.changed', function (event) { var element = event.element, gfx = event.gfx, hit = (0, _minDom.query)('.djs-hit', gfx); (0, _RenderUtil.updateLine)(hit, element.waypoints); }); // API this.fire = fire; this.triggerMouseEvent = triggerMouseEvent; this.mouseHandler = mouseHandler; this.registerEvent = registerEvent; this.unregisterEvent = unregisterEvent; } InteractionEvents.$inject = ['eventBus', 'elementRegistry', 'styles']; /** * An event indicating that the mouse hovered over an element * * @event element.hover * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the mouse has left an element * * @event element.out * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the mouse has clicked an element * * @event element.click * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the mouse has double clicked an element * * @event element.dblclick * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the mouse has gone down on an element. * * @event element.mousedown * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the mouse has gone up on an element. * * @event element.mouseup * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the context menu action is triggered * via mouse or touch controls. * * @event element.contextmenu * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ },{"../../util/Mouse":403,"../../util/RenderUtil":407,"min-dash":505,"min-dom":506,"tiny-svg":535}],294:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _InteractionEvents = require('./InteractionEvents'); var _InteractionEvents2 = _interopRequireDefault(_InteractionEvents); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['interactionEvents'], interactionEvents: ['type', _InteractionEvents2.default] }; },{"./InteractionEvents":293}],295:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = KeyboardMoveSelection; var _minDash = require('min-dash'); var DEFAULT_CONFIG = { moveSpeed: 1, moveSpeedAccelerated: 10 }; var HIGHER_PRIORITY = 1500; var LEFT = 'left'; var UP = 'up'; var RIGHT = 'right'; var DOWN = 'down'; var KEY_TO_DIRECTION = { ArrowLeft: LEFT, Left: LEFT, ArrowUp: UP, Up: UP, ArrowRight: RIGHT, Right: RIGHT, ArrowDown: DOWN, Down: DOWN }; var DIRECTIONS_DELTA = { left: function left(speed) { return { x: -speed, y: 0 }; }, up: function up(speed) { return { x: 0, y: -speed }; }, right: function right(speed) { return { x: speed, y: 0 }; }, down: function down(speed) { return { x: 0, y: speed }; } }; /** * Enables to move selection with keyboard arrows. * Use with Shift for modified speed (default=1, with Shift=10). * Pressed Cmd/Ctrl turns the feature off. * * @param {Object} config * @param {Number} [config.moveSpeed=1] * @param {Number} [config.moveSpeedAccelerated=10] * @param {Keyboard} keyboard * @param {Modeling} modeling * @param {Selection} selection */ function KeyboardMoveSelection(config, keyboard, modeling, selection) { var self = this; this._config = (0, _minDash.assign)({}, DEFAULT_CONFIG, config || {}); keyboard.addListener(HIGHER_PRIORITY, function (event) { var keyEvent = event.keyEvent; var direction = KEY_TO_DIRECTION[keyEvent.key]; if (!direction) { return; } if (keyboard.isCmd(keyEvent)) { return; } var accelerated = keyboard.isShift(keyEvent); self.moveSelection(direction, accelerated); return true; }); /** * Move selected elements in the given direction, * optionally specifying accelerated movement. * * @param {String} direction * @param {Boolean} [accelerated=false] */ this.moveSelection = function (direction, accelerated) { var selectedElements = selection.get(); if (!selectedElements.length) { return; } var speed = this._config[accelerated ? 'moveSpeedAccelerated' : 'moveSpeed']; var delta = DIRECTIONS_DELTA[direction](speed); modeling.moveElements(selectedElements, delta); }; } KeyboardMoveSelection.$inject = ['config.keyboardMoveSelection', 'keyboard', 'modeling', 'selection']; },{"min-dash":505}],296:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _keyboard = require('../keyboard'); var _keyboard2 = _interopRequireDefault(_keyboard); var _selection = require('../selection'); var _selection2 = _interopRequireDefault(_selection); var _KeyboardMoveSelection = require('./KeyboardMoveSelection'); var _KeyboardMoveSelection2 = _interopRequireDefault(_KeyboardMoveSelection); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_keyboard2.default, _selection2.default], __init__: ['keyboardMoveSelection'], keyboardMoveSelection: ['type', _KeyboardMoveSelection2.default] }; },{"../keyboard":300,"../selection":361,"./KeyboardMoveSelection":295}],297:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Keyboard; var _minDash = require('min-dash'); var _minDom = require('min-dom'); var _KeyboardUtil = require('./KeyboardUtil'); var KEYDOWN_EVENT = 'keyboard.keydown'; var DEFAULT_PRIORITY = 1000; /** * A keyboard abstraction that may be activated and * deactivated by users at will, consuming key events * and triggering diagram actions. * * For keys pressed down, keyboard fires `keyboard.keydown` event. * The event context contains one field which is `KeyboardEvent` event. * * The implementation fires the following key events that allow * other components to hook into key handling: * * - keyboard.bind * - keyboard.unbind * - keyboard.init * - keyboard.destroy * * All events contain one field which is node. * * A default binding for the keyboard may be specified via the * `keyboard.bindTo` configuration option. * * @param {Config} config * @param {EventBus} eventBus */ function Keyboard(config, eventBus) { var self = this; this._config = config || {}; this._eventBus = eventBus; this._keyHandler = this._keyHandler.bind(this); // properly clean dom registrations eventBus.on('diagram.destroy', function () { self._fire('destroy'); self.unbind(); }); eventBus.on('diagram.init', function () { self._fire('init'); }); eventBus.on('attach', function () { if (config && config.bindTo) { self.bind(config.bindTo); } }); eventBus.on('detach', function () { self.unbind(); }); } Keyboard.$inject = ['config.keyboard', 'eventBus']; Keyboard.prototype._keyHandler = function (event) { var target = event.target, eventBusResult; if (isInput(target)) { return; } var context = { keyEvent: event }; eventBusResult = this._eventBus.fire(KEYDOWN_EVENT, context); if (eventBusResult) { event.preventDefault(); } }; Keyboard.prototype.bind = function (node) { // make sure that the keyboard is only bound once to the DOM this.unbind(); this._node = node; // bind key events _minDom.event.bind(node, 'keydown', this._keyHandler, true); this._fire('bind'); }; Keyboard.prototype.getBinding = function () { return this._node; }; Keyboard.prototype.unbind = function () { var node = this._node; if (node) { this._fire('unbind'); // unbind key events _minDom.event.unbind(node, 'keydown', this._keyHandler, true); } this._node = null; }; Keyboard.prototype._fire = function (event) { this._eventBus.fire('keyboard.' + event, { node: this._node }); }; /** * Add a listener function that is notified with `KeyboardEvent` whenever * the keyboard is bound and the user presses a key. If no priority is * provided, the default value of 1000 is used. * * @param {Number} priority * @param {Function} listener */ Keyboard.prototype.addListener = function (priority, listener) { if ((0, _minDash.isFunction)(priority)) { listener = priority; priority = DEFAULT_PRIORITY; } this._eventBus.on(KEYDOWN_EVENT, priority, listener); }; Keyboard.prototype.hasModifier = _KeyboardUtil.hasModifier; Keyboard.prototype.isCmd = _KeyboardUtil.isCmd; Keyboard.prototype.isShift = _KeyboardUtil.isShift; Keyboard.prototype.isKey = _KeyboardUtil.isKey; // helpers /////// function isInput(target) { return target && ((0, _minDom.matches)(target, 'input, textarea') || target.contentEditable === 'true'); } },{"./KeyboardUtil":299,"min-dash":505,"min-dom":506}],298:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = KeyboardBindings; var _KeyboardUtil = require('./KeyboardUtil'); var LOW_PRIORITY = 500; /** * Adds default keyboard bindings. * * This does not pull in any features will bind only actions that * have previously been registered against the editorActions component. * * @param {EventBus} eventBus * @param {Keyboard} keyboard */ function KeyboardBindings(eventBus, keyboard) { var self = this; eventBus.on('editorActions.init', LOW_PRIORITY, function (event) { var editorActions = event.editorActions; self.registerBindings(keyboard, editorActions); }); } KeyboardBindings.$inject = ['eventBus', 'keyboard']; /** * Register available keyboard bindings. * * @param {Keyboard} keyboard * @param {EditorActions} editorActions */ KeyboardBindings.prototype.registerBindings = function (keyboard, editorActions) { /** * Add keyboard binding if respective editor action * is registered. * * @param {String} action name * @param {Function} fn that implements the key binding */ function addListener(action, fn) { if (editorActions.isRegistered(action)) { keyboard.addListener(fn); } } // undo // (CTRL|CMD) + Z addListener('undo', function (context) { var event = context.keyEvent; if ((0, _KeyboardUtil.isCmd)(event) && !(0, _KeyboardUtil.isShift)(event) && (0, _KeyboardUtil.isKey)(['z', 'Z'], event)) { editorActions.trigger('undo'); return true; } }); // redo // CTRL + Y // CMD + SHIFT + Z addListener('redo', function (context) { var event = context.keyEvent; if ((0, _KeyboardUtil.isCmd)(event) && ((0, _KeyboardUtil.isKey)(['y', 'Y'], event) || (0, _KeyboardUtil.isKey)(['z', 'Z'], event) && (0, _KeyboardUtil.isShift)(event))) { editorActions.trigger('redo'); return true; } }); // copy // CTRL/CMD + C addListener('copy', function (context) { var event = context.keyEvent; if ((0, _KeyboardUtil.isCmd)(event) && (0, _KeyboardUtil.isKey)(['c', 'C'], event)) { editorActions.trigger('copy'); return true; } }); // paste // CTRL/CMD + V addListener('paste', function (context) { var event = context.keyEvent; if ((0, _KeyboardUtil.isCmd)(event) && (0, _KeyboardUtil.isKey)(['v', 'V'], event)) { editorActions.trigger('paste'); return true; } }); // zoom in one step // CTRL/CMD + + addListener('stepZoom', function (context) { var event = context.keyEvent; if ((0, _KeyboardUtil.isKey)(['+', 'Add'], event) && (0, _KeyboardUtil.isCmd)(event)) { editorActions.trigger('stepZoom', { value: 1 }); return true; } }); // zoom out one step // CTRL + - addListener('stepZoom', function (context) { var event = context.keyEvent; if ((0, _KeyboardUtil.isKey)(['-', 'Subtract'], event) && (0, _KeyboardUtil.isCmd)(event)) { editorActions.trigger('stepZoom', { value: -1 }); return true; } }); // zoom to the default level // CTRL + 0 addListener('zoom', function (context) { var event = context.keyEvent; if ((0, _KeyboardUtil.isKey)('0', event) && (0, _KeyboardUtil.isCmd)(event)) { editorActions.trigger('zoom', { value: 1 }); return true; } }); // delete selected element // DEL addListener('removeSelection', function (context) { var event = context.keyEvent; if ((0, _KeyboardUtil.isKey)(['Delete', 'Del'], event)) { editorActions.trigger('removeSelection'); return true; } }); }; },{"./KeyboardUtil":299}],299:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.hasModifier = hasModifier; exports.isCmd = isCmd; exports.isKey = isKey; exports.isShift = isShift; var _minDash = require('min-dash'); /** * Returns true if event was triggered with any modifier * @param {KeyboardEvent} event */ function hasModifier(event) { return event.ctrlKey || event.metaKey || event.shiftKey || event.altKey; } /** * @param {KeyboardEvent} event */ function isCmd(event) { // ensure we don't react to AltGr // (mapped to CTRL + ALT) if (event.altKey) { return false; } return event.ctrlKey || event.metaKey; } /** * Checks if key pressed is one of provided keys. * * @param {String|String[]} keys * @param {KeyboardEvent} event */ function isKey(keys, event) { keys = (0, _minDash.isArray)(keys) ? keys : [keys]; return keys.indexOf(event.key) > -1; } /** * @param {KeyboardEvent} event */ function isShift(event) { return event.shiftKey; } },{"min-dash":505}],300:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _Keyboard = require('./Keyboard'); var _Keyboard2 = _interopRequireDefault(_Keyboard); var _KeyboardBindings = require('./KeyboardBindings'); var _KeyboardBindings2 = _interopRequireDefault(_KeyboardBindings); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['keyboard', 'keyboardBindings'], keyboard: ['type', _Keyboard2.default], keyboardBindings: ['type', _KeyboardBindings2.default] }; },{"./Keyboard":297,"./KeyboardBindings":298}],301:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = LabelSupport; var _minDash = require('min-dash'); var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _Collections = require('../../util/Collections'); var _Removal = require('../../util/Removal'); var _CommandInterceptor = require('../../command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 250, HIGH_PRIORITY = 1400; /** * A handler that makes sure labels are properly moved with * their label targets. * * @param {didi.Injector} injector * @param {EventBus} eventBus * @param {Modeling} modeling */ function LabelSupport(injector, eventBus, modeling) { _CommandInterceptor2.default.call(this, eventBus); var movePreview = injector.get('movePreview', false); // remove labels from the collection that are being // moved with other elements anyway eventBus.on('shape.move.start', HIGH_PRIORITY, function (e) { var context = e.context, shapes = context.shapes, validatedShapes = context.validatedShapes; context.shapes = removeLabels(shapes); context.validatedShapes = removeLabels(validatedShapes); }); // add labels to visual's group movePreview && eventBus.on('shape.move.start', LOW_PRIORITY, function (e) { var context = e.context, shapes = context.shapes; var labels = []; (0, _minDash.forEach)(shapes, function (element) { (0, _minDash.forEach)(element.labels, function (label) { if (!label.hidden && context.shapes.indexOf(label) === -1) { labels.push(label); } if (element.labelTarget) { labels.push(element); } }); }); (0, _minDash.forEach)(labels, function (label) { movePreview.makeDraggable(context, label, true); }); }); // add all labels to move closure this.preExecuted('elements.move', HIGH_PRIORITY, function (e) { var context = e.context, closure = context.closure, enclosedElements = closure.enclosedElements; var enclosedLabels = []; // find labels that are not part of // move closure yet and add them (0, _minDash.forEach)(enclosedElements, function (element) { (0, _minDash.forEach)(element.labels, function (label) { if (!enclosedElements[label.id]) { enclosedLabels.push(label); } }); }); closure.addAll(enclosedLabels); }); this.preExecute(['connection.delete', 'shape.delete'], function (e) { var context = e.context, element = context.connection || context.shape; (0, _Removal.saveClear)(element.labels, function (label) { modeling.removeShape(label, { nested: true }); }); }); this.execute('shape.delete', function (e) { var context = e.context, shape = context.shape, labelTarget = shape.labelTarget; // unset labelTarget if (labelTarget) { context.labelTargetIndex = (0, _Collections.indexOf)(labelTarget.labels, shape); context.labelTarget = labelTarget; shape.labelTarget = null; } }); this.revert('shape.delete', function (e) { var context = e.context, shape = context.shape, labelTarget = context.labelTarget, labelTargetIndex = context.labelTargetIndex; // restore labelTarget if (labelTarget) { (0, _Collections.add)(labelTarget.labels, shape, labelTargetIndex); shape.labelTarget = labelTarget; } }); } (0, _inherits2.default)(LabelSupport, _CommandInterceptor2.default); LabelSupport.$inject = ['injector', 'eventBus', 'modeling']; /** * Return a filtered list of elements that do not * contain attached elements with hosts being part * of the selection. * * @param {Array} elements * * @return {Array} filtered */ function removeLabels(elements) { return (0, _minDash.filter)(elements, function (element) { // filter out labels that are move together // with their label targets return elements.indexOf(element.labelTarget) === -1; }); } },{"../../command/CommandInterceptor":243,"../../util/Collections":393,"../../util/Removal":406,"inherits":415,"min-dash":505}],302:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _LabelSupport = require('./LabelSupport'); var _LabelSupport2 = _interopRequireDefault(_LabelSupport); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['labelSupport'], labelSupport: ['type', _LabelSupport2.default] }; },{"./LabelSupport":301}],303:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = LassoTool; var _minDash = require('min-dash'); var _Elements = require('../../util/Elements'); var _Mouse = require('../../util/Mouse'); var _tinySvg = require('tiny-svg'); var LASSO_TOOL_CURSOR = 'crosshair'; function LassoTool(eventBus, canvas, dragging, elementRegistry, selection, toolManager) { this._selection = selection; this._dragging = dragging; var self = this; // lasso visuals implementation /** * A helper that realizes the selection box visual */ var visuals = { create: function create(context) { var container = canvas.getDefaultLayer(), frame; frame = context.frame = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(frame, { class: 'djs-lasso-overlay', width: 1, height: 1, x: 0, y: 0 }); (0, _tinySvg.append)(container, frame); }, update: function update(context) { var frame = context.frame, bbox = context.bbox; (0, _tinySvg.attr)(frame, { x: bbox.x, y: bbox.y, width: bbox.width, height: bbox.height }); }, remove: function remove(context) { if (context.frame) { (0, _tinySvg.remove)(context.frame); } } }; toolManager.registerTool('lasso', { tool: 'lasso.selection', dragging: 'lasso' }); eventBus.on('lasso.selection.end', function (event) { var target = event.originalEvent.target; // only reactive on diagram click // on some occasions, event.hover is not set and we have to check if the target is an svg if (!event.hover && !(target instanceof SVGElement)) { return; } eventBus.once('lasso.selection.ended', function () { self.activateLasso(event.originalEvent, true); }); }); // lasso interaction implementation eventBus.on('lasso.end', function (event) { var bbox = toBBox(event); var elements = elementRegistry.filter(function (element) { return element; }); self.select(elements, bbox); }); eventBus.on('lasso.start', function (event) { var context = event.context; context.bbox = toBBox(event); visuals.create(context); }); eventBus.on('lasso.move', function (event) { var context = event.context; context.bbox = toBBox(event); visuals.update(context); }); eventBus.on('lasso.cleanup', function (event) { var context = event.context; visuals.remove(context); }); // event integration eventBus.on('element.mousedown', 1500, function (event) { if ((0, _Mouse.hasSecondaryModifier)(event)) { self.activateLasso(event.originalEvent); // we've handled the event return true; } }); } LassoTool.$inject = ['eventBus', 'canvas', 'dragging', 'elementRegistry', 'selection', 'toolManager']; LassoTool.prototype.activateLasso = function (event, autoActivate) { this._dragging.init(event, 'lasso', { autoActivate: autoActivate, cursor: LASSO_TOOL_CURSOR, data: { context: {} } }); }; LassoTool.prototype.activateSelection = function (event) { this._dragging.init(event, 'lasso.selection', { trapClick: false, cursor: LASSO_TOOL_CURSOR, data: { context: {} } }); }; LassoTool.prototype.select = function (elements, bbox) { var selectedElements = (0, _Elements.getEnclosedElements)(elements, bbox); this._selection.select((0, _minDash.values)(selectedElements)); }; LassoTool.prototype.toggle = function () { if (this.isActive()) { this._dragging.cancel(); } else { this.activateSelection(); } }; LassoTool.prototype.isActive = function () { var context = this._dragging.context(); return context && /^lasso/.test(context.prefix); }; function toBBox(event) { var start = { x: event.x - event.dx, y: event.y - event.dy }; var end = { x: event.x, y: event.y }; var bbox; if (start.x <= end.x && start.y < end.y || start.x < end.x && start.y <= end.y) { bbox = { x: start.x, y: start.y, width: end.x - start.x, height: end.y - start.y }; } else if (start.x >= end.x && start.y < end.y || start.x > end.x && start.y <= end.y) { bbox = { x: end.x, y: start.y, width: start.x - end.x, height: end.y - start.y }; } else if (start.x <= end.x && start.y > end.y || start.x < end.x && start.y >= end.y) { bbox = { x: start.x, y: end.y, width: end.x - start.x, height: start.y - end.y }; } else if (start.x >= end.x && start.y > end.y || start.x > end.x && start.y >= end.y) { bbox = { x: end.x, y: end.y, width: start.x - end.x, height: start.y - end.y }; } else { bbox = { x: end.x, y: end.y, width: 0, height: 0 }; } return bbox; } },{"../../util/Elements":396,"../../util/Mouse":403,"min-dash":505,"tiny-svg":535}],304:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _toolManager = require('../tool-manager'); var _toolManager2 = _interopRequireDefault(_toolManager); var _LassoTool = require('./LassoTool'); var _LassoTool2 = _interopRequireDefault(_LassoTool); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_toolManager2.default], __init__: ['lassoTool'], lassoTool: ['type', _LassoTool2.default] }; },{"../tool-manager":370,"./LassoTool":303}],305:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; exports.default = Modeling; var _minDash = require('min-dash'); var _model = require('../../model'); var _AppendShapeHandler = require('./cmd/AppendShapeHandler'); var _AppendShapeHandler2 = _interopRequireDefault(_AppendShapeHandler); var _CreateShapeHandler = require('./cmd/CreateShapeHandler'); var _CreateShapeHandler2 = _interopRequireDefault(_CreateShapeHandler); var _DeleteShapeHandler = require('./cmd/DeleteShapeHandler'); var _DeleteShapeHandler2 = _interopRequireDefault(_DeleteShapeHandler); var _MoveShapeHandler = require('./cmd/MoveShapeHandler'); var _MoveShapeHandler2 = _interopRequireDefault(_MoveShapeHandler); var _ResizeShapeHandler = require('./cmd/ResizeShapeHandler'); var _ResizeShapeHandler2 = _interopRequireDefault(_ResizeShapeHandler); var _ReplaceShapeHandler = require('./cmd/ReplaceShapeHandler'); var _ReplaceShapeHandler2 = _interopRequireDefault(_ReplaceShapeHandler); var _ToggleShapeCollapseHandler = require('./cmd/ToggleShapeCollapseHandler'); var _ToggleShapeCollapseHandler2 = _interopRequireDefault(_ToggleShapeCollapseHandler); var _SpaceToolHandler = require('./cmd/SpaceToolHandler'); var _SpaceToolHandler2 = _interopRequireDefault(_SpaceToolHandler); var _CreateLabelHandler = require('./cmd/CreateLabelHandler'); var _CreateLabelHandler2 = _interopRequireDefault(_CreateLabelHandler); var _CreateConnectionHandler = require('./cmd/CreateConnectionHandler'); var _CreateConnectionHandler2 = _interopRequireDefault(_CreateConnectionHandler); var _DeleteConnectionHandler = require('./cmd/DeleteConnectionHandler'); var _DeleteConnectionHandler2 = _interopRequireDefault(_DeleteConnectionHandler); var _MoveConnectionHandler = require('./cmd/MoveConnectionHandler'); var _MoveConnectionHandler2 = _interopRequireDefault(_MoveConnectionHandler); var _LayoutConnectionHandler = require('./cmd/LayoutConnectionHandler'); var _LayoutConnectionHandler2 = _interopRequireDefault(_LayoutConnectionHandler); var _UpdateWaypointsHandler = require('./cmd/UpdateWaypointsHandler'); var _UpdateWaypointsHandler2 = _interopRequireDefault(_UpdateWaypointsHandler); var _ReconnectConnectionHandler = require('./cmd/ReconnectConnectionHandler'); var _ReconnectConnectionHandler2 = _interopRequireDefault(_ReconnectConnectionHandler); var _MoveElementsHandler = require('./cmd/MoveElementsHandler'); var _MoveElementsHandler2 = _interopRequireDefault(_MoveElementsHandler); var _DeleteElementsHandler = require('./cmd/DeleteElementsHandler'); var _DeleteElementsHandler2 = _interopRequireDefault(_DeleteElementsHandler); var _DistributeElementsHandler = require('./cmd/DistributeElementsHandler'); var _DistributeElementsHandler2 = _interopRequireDefault(_DistributeElementsHandler); var _AlignElementsHandler = require('./cmd/AlignElementsHandler'); var _AlignElementsHandler2 = _interopRequireDefault(_AlignElementsHandler); var _UpdateAttachmentHandler = require('./cmd/UpdateAttachmentHandler'); var _UpdateAttachmentHandler2 = _interopRequireDefault(_UpdateAttachmentHandler); var _PasteHandler = require('./cmd/PasteHandler'); var _PasteHandler2 = _interopRequireDefault(_PasteHandler); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * The basic modeling entry point. * * @param {EventBus} eventBus * @param {ElementFactory} elementFactory * @param {CommandStack} commandStack */ function Modeling(eventBus, elementFactory, commandStack) { this._eventBus = eventBus; this._elementFactory = elementFactory; this._commandStack = commandStack; var self = this; eventBus.on('diagram.init', function () { // register modeling handlers self.registerHandlers(commandStack); }); } Modeling.$inject = ['eventBus', 'elementFactory', 'commandStack']; Modeling.prototype.getHandlers = function () { return { 'shape.append': _AppendShapeHandler2.default, 'shape.create': _CreateShapeHandler2.default, 'shape.delete': _DeleteShapeHandler2.default, 'shape.move': _MoveShapeHandler2.default, 'shape.resize': _ResizeShapeHandler2.default, 'shape.replace': _ReplaceShapeHandler2.default, 'shape.toggleCollapse': _ToggleShapeCollapseHandler2.default, 'spaceTool': _SpaceToolHandler2.default, 'label.create': _CreateLabelHandler2.default, 'connection.create': _CreateConnectionHandler2.default, 'connection.delete': _DeleteConnectionHandler2.default, 'connection.move': _MoveConnectionHandler2.default, 'connection.layout': _LayoutConnectionHandler2.default, 'connection.updateWaypoints': _UpdateWaypointsHandler2.default, 'connection.reconnectStart': _ReconnectConnectionHandler2.default, 'connection.reconnectEnd': _ReconnectConnectionHandler2.default, 'elements.move': _MoveElementsHandler2.default, 'elements.delete': _DeleteElementsHandler2.default, 'elements.distribute': _DistributeElementsHandler2.default, 'elements.align': _AlignElementsHandler2.default, 'element.updateAttachment': _UpdateAttachmentHandler2.default, 'elements.paste': _PasteHandler2.default }; }; /** * Register handlers with the command stack * * @param {CommandStack} commandStack */ Modeling.prototype.registerHandlers = function (commandStack) { (0, _minDash.forEach)(this.getHandlers(), function (handler, id) { commandStack.registerHandler(id, handler); }); }; // modeling helpers ////////////////////// Modeling.prototype.moveShape = function (shape, delta, newParent, newParentIndex, hints) { if ((typeof newParentIndex === 'undefined' ? 'undefined' : _typeof(newParentIndex)) === 'object') { hints = newParentIndex; newParentIndex = null; } var context = { shape: shape, delta: delta, newParent: newParent, newParentIndex: newParentIndex, hints: hints || {} }; this._commandStack.execute('shape.move', context); }; /** * Update the attachment of the given shape. * * @param {djs.mode.Base} shape * @param {djs.model.Base} [newHost] */ Modeling.prototype.updateAttachment = function (shape, newHost) { var context = { shape: shape, newHost: newHost }; this._commandStack.execute('element.updateAttachment', context); }; /** * Move a number of shapes to a new target, either setting it as * the new parent or attaching it. * * @param {Array} shapes * @param {Point} delta * @param {djs.model.Base} [target] * @param {Object} [hints] * @param {Boolean} [hints.attach=false] */ Modeling.prototype.moveElements = function (shapes, delta, target, hints) { hints = hints || {}; var attach = hints.attach; var newParent = target, newHost; if (attach === true) { newHost = target; newParent = target.parent; } else if (attach === false) { newHost = null; } var context = { shapes: shapes, delta: delta, newParent: newParent, newHost: newHost, hints: hints }; this._commandStack.execute('elements.move', context); }; Modeling.prototype.moveConnection = function (connection, delta, newParent, newParentIndex, hints) { if ((typeof newParentIndex === 'undefined' ? 'undefined' : _typeof(newParentIndex)) === 'object') { hints = newParentIndex; newParentIndex = undefined; } var context = { connection: connection, delta: delta, newParent: newParent, newParentIndex: newParentIndex, hints: hints || {} }; this._commandStack.execute('connection.move', context); }; Modeling.prototype.layoutConnection = function (connection, hints) { var context = { connection: connection, hints: hints || {} }; this._commandStack.execute('connection.layout', context); }; /** * Create connection. * * @param {djs.model.Base} source * @param {djs.model.Base} target * @param {Number} [targetIndex] * @param {Object|djs.model.Connection} connection * @param {djs.model.Base} parent * @param {Object} hints * * @return {djs.model.Connection} the created connection. */ Modeling.prototype.createConnection = function (source, target, parentIndex, connection, parent, hints) { if ((typeof parentIndex === 'undefined' ? 'undefined' : _typeof(parentIndex)) === 'object') { hints = parent; parent = connection; connection = parentIndex; parentIndex = undefined; } connection = this._create('connection', connection); var context = { source: source, target: target, parent: parent, parentIndex: parentIndex, connection: connection, hints: hints }; this._commandStack.execute('connection.create', context); return context.connection; }; /** * Create a shape at the specified position. * * @param {djs.model.Shape|Object} shape * @param {Point} position * @param {djs.model.Shape|djs.model.Root} target * @param {Number} [parentIndex] position in parents children list * @param {Object} [hints] * @param {Boolean} [hints.attach] whether to attach to target or become a child * * @return {djs.model.Shape} the created shape */ Modeling.prototype.createShape = function (shape, position, target, parentIndex, hints) { if (typeof parentIndex !== 'number') { hints = parentIndex; parentIndex = undefined; } hints = hints || {}; var attach = hints.attach, parent, host; shape = this._create('shape', shape); if (attach) { parent = target.parent; host = target; } else { parent = target; } var context = { position: position, shape: shape, parent: parent, parentIndex: parentIndex, host: host, hints: hints }; this._commandStack.execute('shape.create', context); return context.shape; }; Modeling.prototype.createLabel = function (labelTarget, position, label, parent) { label = this._create('label', label); var context = { labelTarget: labelTarget, position: position, parent: parent || labelTarget.parent, shape: label }; this._commandStack.execute('label.create', context); return context.shape; }; /** * Append shape to given source, drawing a connection * between source and the newly created shape. * * @param {djs.model.Shape} source * @param {djs.model.Shape|Object} shape * @param {Point} position * @param {djs.model.Shape} target * @param {Object} [hints] * @param {Boolean} [hints.attach] * @param {djs.model.Connection|Object} [hints.connection] * @param {djs.model.Base} [hints.connectionParent] * * @return {djs.model.Shape} the newly created shape */ Modeling.prototype.appendShape = function (source, shape, position, target, hints) { hints = hints || {}; shape = this._create('shape', shape); var context = { source: source, position: position, target: target, shape: shape, connection: hints.connection, connectionParent: hints.connectionParent, attach: hints.attach }; this._commandStack.execute('shape.append', context); return context.shape; }; Modeling.prototype.removeElements = function (elements) { var context = { elements: elements }; this._commandStack.execute('elements.delete', context); }; Modeling.prototype.distributeElements = function (groups, axis, dimension) { var context = { groups: groups, axis: axis, dimension: dimension }; this._commandStack.execute('elements.distribute', context); }; Modeling.prototype.removeShape = function (shape, hints) { var context = { shape: shape, hints: hints || {} }; this._commandStack.execute('shape.delete', context); }; Modeling.prototype.removeConnection = function (connection, hints) { var context = { connection: connection, hints: hints || {} }; this._commandStack.execute('connection.delete', context); }; Modeling.prototype.replaceShape = function (oldShape, newShape, hints) { var context = { oldShape: oldShape, newData: newShape, hints: hints || {} }; this._commandStack.execute('shape.replace', context); return context.newShape; }; Modeling.prototype.pasteElements = function (tree, topParent, position) { var context = { tree: tree, topParent: topParent, position: position }; this._commandStack.execute('elements.paste', context); }; Modeling.prototype.alignElements = function (elements, alignment) { var context = { elements: elements, alignment: alignment }; this._commandStack.execute('elements.align', context); }; Modeling.prototype.resizeShape = function (shape, newBounds, minBounds) { var context = { shape: shape, newBounds: newBounds, minBounds: minBounds }; this._commandStack.execute('shape.resize', context); }; Modeling.prototype.createSpace = function (movingShapes, resizingShapes, delta, direction) { var context = { movingShapes: movingShapes, resizingShapes: resizingShapes, delta: delta, direction: direction }; this._commandStack.execute('spaceTool', context); }; Modeling.prototype.updateWaypoints = function (connection, newWaypoints, hints) { var context = { connection: connection, newWaypoints: newWaypoints, hints: hints || {} }; this._commandStack.execute('connection.updateWaypoints', context); }; Modeling.prototype.reconnectStart = function (connection, newSource, dockingOrPoints) { var context = { connection: connection, newSource: newSource, dockingOrPoints: dockingOrPoints }; this._commandStack.execute('connection.reconnectStart', context); }; Modeling.prototype.reconnectEnd = function (connection, newTarget, dockingOrPoints) { var context = { connection: connection, newTarget: newTarget, dockingOrPoints: dockingOrPoints }; this._commandStack.execute('connection.reconnectEnd', context); }; Modeling.prototype.connect = function (source, target, attrs, hints) { return this.createConnection(source, target, attrs || {}, source.parent, hints); }; Modeling.prototype._create = function (type, attrs) { if (attrs instanceof _model.Base) { return attrs; } else { return this._elementFactory.create(type, attrs); } }; Modeling.prototype.toggleCollapse = function (shape, hints) { var context = { shape: shape, hints: hints || {} }; this._commandStack.execute('shape.toggleCollapse', context); }; },{"../../model":382,"./cmd/AlignElementsHandler":306,"./cmd/AppendShapeHandler":307,"./cmd/CreateConnectionHandler":308,"./cmd/CreateLabelHandler":309,"./cmd/CreateShapeHandler":310,"./cmd/DeleteConnectionHandler":311,"./cmd/DeleteElementsHandler":312,"./cmd/DeleteShapeHandler":313,"./cmd/DistributeElementsHandler":314,"./cmd/LayoutConnectionHandler":315,"./cmd/MoveConnectionHandler":316,"./cmd/MoveElementsHandler":317,"./cmd/MoveShapeHandler":318,"./cmd/PasteHandler":319,"./cmd/ReconnectConnectionHandler":320,"./cmd/ReplaceShapeHandler":321,"./cmd/ResizeShapeHandler":322,"./cmd/SpaceToolHandler":323,"./cmd/ToggleShapeCollapseHandler":324,"./cmd/UpdateAttachmentHandler":325,"./cmd/UpdateWaypointsHandler":326,"min-dash":505}],306:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AlignElements; var _minDash = require('min-dash'); /** * A handler that align elements in a certain way. * */ function AlignElements(modeling, canvas) { this._modeling = modeling; this._canvas = canvas; } AlignElements.$inject = ['modeling', 'canvas']; AlignElements.prototype.preExecute = function (context) { var modeling = this._modeling; var elements = context.elements, alignment = context.alignment; (0, _minDash.forEach)(elements, function (element) { var delta = { x: 0, y: 0 }; if (alignment.left) { delta.x = alignment.left - element.x; } else if (alignment.right) { delta.x = alignment.right - element.width - element.x; } else if (alignment.center) { delta.x = alignment.center - Math.round(element.width / 2) - element.x; } else if (alignment.top) { delta.y = alignment.top - element.y; } else if (alignment.bottom) { delta.y = alignment.bottom - element.height - element.y; } else if (alignment.middle) { delta.y = alignment.middle - Math.round(element.height / 2) - element.y; } modeling.moveElements([element], delta, element.parent); }); }; AlignElements.prototype.postExecute = function (context) {}; },{"min-dash":505}],307:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AppendShapeHandler; var _minDash = require('min-dash'); /** * A handler that implements reversible appending of shapes * to a source shape. * * @param {canvas} Canvas * @param {elementFactory} ElementFactory * @param {modeling} Modeling */ function AppendShapeHandler(modeling) { this._modeling = modeling; } AppendShapeHandler.$inject = ['modeling']; // api ////////////////////// /** * Creates a new shape * * @param {Object} context * @param {ElementDescriptor} context.shape the new shape * @param {ElementDescriptor} context.source the source object * @param {ElementDescriptor} context.parent the parent object * @param {Point} context.position position of the new element */ AppendShapeHandler.prototype.preExecute = function (context) { var source = context.source; if (!source) { throw new Error('source required'); } var target = context.target || source.parent, shape = context.shape; shape = context.shape = this._modeling.createShape(shape, context.position, target, { attach: context.attach }); context.shape = shape; }; AppendShapeHandler.prototype.postExecute = function (context) { var parent = context.connectionParent || context.shape.parent; if (!existsConnection(context.source, context.shape)) { // create connection this._modeling.connect(context.source, context.shape, context.connection, parent); } }; function existsConnection(source, target) { return (0, _minDash.some)(source.outgoing, function (c) { return c.target === target; }); } },{"min-dash":505}],308:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateConnectionHandler; function CreateConnectionHandler(canvas, layouter) { this._canvas = canvas; this._layouter = layouter; } CreateConnectionHandler.$inject = ['canvas', 'layouter']; // api ////////////////////// /** * Appends a shape to a target shape * * @param {Object} context * @param {djs.element.Base} context.source the source object * @param {djs.element.Base} context.target the parent object * @param {Point} context.position position of the new element */ CreateConnectionHandler.prototype.execute = function (context) { var connection = context.connection, source = context.source, target = context.target, parent = context.parent, parentIndex = context.parentIndex, hints = context.hints; if (!source || !target) { throw new Error('source and target required'); } if (!parent) { throw new Error('parent required'); } connection.source = source; connection.target = target; if (!connection.waypoints) { connection.waypoints = this._layouter.layoutConnection(connection, hints); } // add connection this._canvas.addConnection(connection, parent, parentIndex); return connection; }; CreateConnectionHandler.prototype.revert = function (context) { var connection = context.connection; this._canvas.removeConnection(connection); connection.source = null; connection.target = null; }; },{}],309:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateLabelHandler; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CreateShapeHandler = require('./CreateShapeHandler'); var _CreateShapeHandler2 = _interopRequireDefault(_CreateShapeHandler); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A handler that attaches a label to a given target shape. * * @param {Canvas} canvas */ function CreateLabelHandler(canvas) { _CreateShapeHandler2.default.call(this, canvas); } (0, _inherits2.default)(CreateLabelHandler, _CreateShapeHandler2.default); CreateLabelHandler.$inject = ['canvas']; // api ////////////////////// var originalExecute = _CreateShapeHandler2.default.prototype.execute; /** * Appends a label to a target shape. * * @method CreateLabelHandler#execute * * @param {Object} context * @param {ElementDescriptor} context.target the element the label is attached to * @param {ElementDescriptor} context.parent the parent object * @param {Point} context.position position of the new element */ CreateLabelHandler.prototype.execute = function (context) { var label = context.shape; ensureValidDimensions(label); label.labelTarget = context.labelTarget; return originalExecute.call(this, context); }; var originalRevert = _CreateShapeHandler2.default.prototype.revert; /** * Undo append by removing the shape */ CreateLabelHandler.prototype.revert = function (context) { context.shape.labelTarget = null; return originalRevert.call(this, context); }; // helpers ////////////////////// function ensureValidDimensions(label) { // make sure a label has valid { width, height } dimensions ['width', 'height'].forEach(function (prop) { if (typeof label[prop] === 'undefined') { label[prop] = 0; } }); } },{"./CreateShapeHandler":310,"inherits":415}],310:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateShapeHandler; var _minDash = require('min-dash'); var round = Math.round; /** * A handler that implements reversible addition of shapes. * * @param {canvas} Canvas */ function CreateShapeHandler(canvas) { this._canvas = canvas; } CreateShapeHandler.$inject = ['canvas']; // api ////////////////////// /** * Appends a shape to a target shape * * @param {Object} context * @param {djs.model.Base} context.parent the parent object * @param {Point} context.position position of the new element */ CreateShapeHandler.prototype.execute = function (context) { var shape = context.shape, positionOrBounds = context.position, parent = context.parent, parentIndex = context.parentIndex; if (!parent) { throw new Error('parent required'); } if (!positionOrBounds) { throw new Error('position required'); } // (1) add at event center position _or_ at given bounds if (positionOrBounds.width !== undefined) { (0, _minDash.assign)(shape, positionOrBounds); } else { (0, _minDash.assign)(shape, { x: positionOrBounds.x - round(shape.width / 2), y: positionOrBounds.y - round(shape.height / 2) }); } // (2) add to canvas this._canvas.addShape(shape, parent, parentIndex); return shape; }; /** * Undo append by removing the shape */ CreateShapeHandler.prototype.revert = function (context) { // (3) remove form canvas this._canvas.removeShape(context.shape); }; },{"min-dash":505}],311:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DeleteConnectionHandler; var _Collections = require('../../../util/Collections'); /** * A handler that implements reversible deletion of Connections. */ function DeleteConnectionHandler(canvas, modeling) { this._canvas = canvas; this._modeling = modeling; } DeleteConnectionHandler.$inject = ['canvas', 'modeling']; DeleteConnectionHandler.prototype.execute = function (context) { var connection = context.connection, parent = connection.parent; context.parent = parent; // remember containment context.parentIndex = (0, _Collections.indexOf)(parent.children, connection); context.source = connection.source; context.target = connection.target; this._canvas.removeConnection(connection); connection.source = null; connection.target = null; return connection; }; /** * Command revert implementation. */ DeleteConnectionHandler.prototype.revert = function (context) { var connection = context.connection, parent = context.parent, parentIndex = context.parentIndex; connection.source = context.source; connection.target = context.target; // restore containment (0, _Collections.add)(parent.children, connection, parentIndex); this._canvas.addConnection(connection, parent); return connection; }; },{"../../../util/Collections":393}],312:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DeleteElementsHandler; var _minDash = require('min-dash'); function DeleteElementsHandler(modeling, elementRegistry) { this._modeling = modeling; this._elementRegistry = elementRegistry; } DeleteElementsHandler.$inject = ['modeling', 'elementRegistry']; DeleteElementsHandler.prototype.postExecute = function (context) { var modeling = this._modeling, elementRegistry = this._elementRegistry, elements = context.elements; (0, _minDash.forEach)(elements, function (element) { // element may have been removed with previous // remove operations already (e.g. in case of nesting) if (!elementRegistry.get(element.id)) { return; } if (element.waypoints) { modeling.removeConnection(element); } else { modeling.removeShape(element); } }); }; },{"min-dash":505}],313:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DeleteShapeHandler; var _Collections = require('../../../util/Collections'); var _Removal = require('../../../util/Removal'); /** * A handler that implements reversible deletion of shapes. * */ function DeleteShapeHandler(canvas, modeling) { this._canvas = canvas; this._modeling = modeling; } DeleteShapeHandler.$inject = ['canvas', 'modeling']; /** * - Remove connections * - Remove all direct children */ DeleteShapeHandler.prototype.preExecute = function (context) { var modeling = this._modeling; var shape = context.shape; // remove connections (0, _Removal.saveClear)(shape.incoming, function (connection) { // To make sure that the connection isn't removed twice // For example if a container is removed modeling.removeConnection(connection, { nested: true }); }); (0, _Removal.saveClear)(shape.outgoing, function (connection) { modeling.removeConnection(connection, { nested: true }); }); // remove child shapes and connections (0, _Removal.saveClear)(shape.children, function (child) { if (isConnection(child)) { modeling.removeConnection(child, { nested: true }); } else { modeling.removeShape(child, { nested: true }); } }); }; /** * Remove shape and remember the parent */ DeleteShapeHandler.prototype.execute = function (context) { var canvas = this._canvas; var shape = context.shape, oldParent = shape.parent; context.oldParent = oldParent; // remove containment context.oldParentIndex = (0, _Collections.indexOf)(oldParent.children, shape); // remove shape canvas.removeShape(shape); return shape; }; /** * Command revert implementation */ DeleteShapeHandler.prototype.revert = function (context) { var canvas = this._canvas; var shape = context.shape, oldParent = context.oldParent, oldParentIndex = context.oldParentIndex; // restore containment (0, _Collections.add)(oldParent.children, shape, oldParentIndex); canvas.addShape(shape, oldParent); return shape; }; function isConnection(element) { return element.waypoints; } },{"../../../util/Collections":393,"../../../util/Removal":406}],314:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DistributeElements; var _minDash = require('min-dash'); /** * A handler that distributes elements evenly. */ function DistributeElements(modeling) { this._modeling = modeling; } DistributeElements.$inject = ['modeling']; var OFF_AXIS = { x: 'y', y: 'x' }; DistributeElements.prototype.preExecute = function (context) { var modeling = this._modeling; var groups = context.groups, axis = context.axis, dimension = context.dimension; function updateRange(group, element) { group.range.min = Math.min(element[axis], group.range.min); group.range.max = Math.max(element[axis] + element[dimension], group.range.max); } function center(element) { return element[axis] + element[dimension] / 2; } function lastIdx(arr) { return arr.length - 1; } function rangeDiff(range) { return range.max - range.min; } function centerElement(refCenter, element) { var delta = { y: 0 }; delta[axis] = refCenter - center(element); if (delta[axis]) { delta[OFF_AXIS[axis]] = 0; modeling.moveElements([element], delta, element.parent); } } var firstGroup = groups[0], lastGroupIdx = lastIdx(groups), lastGroup = groups[lastGroupIdx]; var margin, spaceInBetween, groupsSize = 0; // the size of each range (0, _minDash.forEach)(groups, function (group, idx) { var sortedElements, refElem, refCenter; if (group.elements.length < 2) { if (idx && idx !== groups.length - 1) { updateRange(group, group.elements[0]); groupsSize += rangeDiff(group.range); } return; } sortedElements = (0, _minDash.sortBy)(group.elements, axis); refElem = sortedElements[0]; if (idx === lastGroupIdx) { refElem = sortedElements[lastIdx(sortedElements)]; } refCenter = center(refElem); // wanna update the ranges after the shapes have been centered group.range = null; (0, _minDash.forEach)(sortedElements, function (element) { centerElement(refCenter, element); if (group.range === null) { group.range = { min: element[axis], max: element[axis] + element[dimension] }; return; } // update group's range after centering the range elements updateRange(group, element); }); if (idx && idx !== groups.length - 1) { groupsSize += rangeDiff(group.range); } }); spaceInBetween = Math.abs(lastGroup.range.min - firstGroup.range.max); margin = Math.round((spaceInBetween - groupsSize) / (groups.length - 1)); if (margin < groups.length - 1) { return; } (0, _minDash.forEach)(groups, function (group, groupIdx) { var delta = {}, prevGroup; if (group === firstGroup || group === lastGroup) { return; } prevGroup = groups[groupIdx - 1]; group.range.max = 0; (0, _minDash.forEach)(group.elements, function (element, idx) { delta[OFF_AXIS[axis]] = 0; delta[axis] = prevGroup.range.max - element[axis] + margin; if (group.range.min !== element[axis]) { delta[axis] += element[axis] - group.range.min; } if (delta[axis]) { modeling.moveElements([element], delta, element.parent); } group.range.max = Math.max(element[axis] + element[dimension], idx ? group.range.max : 0); }); }); }; DistributeElements.prototype.postExecute = function (context) {}; },{"min-dash":505}],315:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = LayoutConnectionHandler; var _minDash = require('min-dash'); /** * A handler that implements reversible moving of shapes. */ function LayoutConnectionHandler(layouter, canvas) { this._layouter = layouter; this._canvas = canvas; } LayoutConnectionHandler.$inject = ['layouter', 'canvas']; LayoutConnectionHandler.prototype.execute = function (context) { var connection = context.connection; var oldWaypoints = connection.waypoints; (0, _minDash.assign)(context, { oldWaypoints: oldWaypoints }); connection.waypoints = this._layouter.layoutConnection(connection, context.hints); return connection; }; LayoutConnectionHandler.prototype.revert = function (context) { var connection = context.connection; connection.waypoints = context.oldWaypoints; return connection; }; },{"min-dash":505}],316:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MoveConnectionHandler; var _minDash = require('min-dash'); var _Collections = require('../../../util/Collections'); /** * A handler that implements reversible moving of connections. * * The handler differs from the layout connection handler in a sense * that it preserves the connection layout. */ function MoveConnectionHandler() {} MoveConnectionHandler.prototype.execute = function (context) { var connection = context.connection, delta = context.delta; var newParent = context.newParent || connection.parent, newParentIndex = context.newParentIndex, oldParent = connection.parent; // save old parent in context context.oldParent = oldParent; context.oldParentIndex = (0, _Collections.remove)(oldParent.children, connection); // add to new parent at position (0, _Collections.add)(newParent.children, connection, newParentIndex); // update parent connection.parent = newParent; // update waypoint positions (0, _minDash.forEach)(connection.waypoints, function (p) { p.x += delta.x; p.y += delta.y; if (p.original) { p.original.x += delta.x; p.original.y += delta.y; } }); return connection; }; MoveConnectionHandler.prototype.revert = function (context) { var connection = context.connection, newParent = connection.parent, oldParent = context.oldParent, oldParentIndex = context.oldParentIndex, delta = context.delta; // remove from newParent (0, _Collections.remove)(newParent.children, connection); // restore previous location in old parent (0, _Collections.add)(oldParent.children, connection, oldParentIndex); // restore parent connection.parent = oldParent; // revert to old waypoint positions (0, _minDash.forEach)(connection.waypoints, function (p) { p.x -= delta.x; p.y -= delta.y; if (p.original) { p.original.x -= delta.x; p.original.y -= delta.y; } }); return connection; }; },{"../../../util/Collections":393,"min-dash":505}],317:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MoveElementsHandler; var _MoveHelper = require('./helper/MoveHelper'); var _MoveHelper2 = _interopRequireDefault(_MoveHelper); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A handler that implements reversible moving of shapes. */ function MoveElementsHandler(modeling) { this._helper = new _MoveHelper2.default(modeling); } MoveElementsHandler.$inject = ['modeling']; MoveElementsHandler.prototype.preExecute = function (context) { context.closure = this._helper.getClosure(context.shapes); }; MoveElementsHandler.prototype.postExecute = function (context) { var hints = context.hints, primaryShape; if (hints && hints.primaryShape) { primaryShape = hints.primaryShape; hints.oldParent = primaryShape.parent; } this._helper.moveClosure(context.closure, context.delta, context.newParent, context.newHost, primaryShape); }; },{"./helper/MoveHelper":329}],318:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MoveShapeHandler; var _minDash = require('min-dash'); var _MoveHelper = require('./helper/MoveHelper'); var _MoveHelper2 = _interopRequireDefault(_MoveHelper); var _Collections = require('../../../util/Collections'); var _AnchorsHelper = require('./helper/AnchorsHelper'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A handler that implements reversible moving of shapes. */ function MoveShapeHandler(modeling) { this._modeling = modeling; this._helper = new _MoveHelper2.default(modeling); } MoveShapeHandler.$inject = ['modeling']; MoveShapeHandler.prototype.execute = function (context) { var shape = context.shape, delta = context.delta, newParent = context.newParent || shape.parent, newParentIndex = context.newParentIndex, oldParent = shape.parent; context.oldBounds = (0, _minDash.pick)(shape, ['x', 'y', 'width', 'height']); // save old parent in context context.oldParent = oldParent; context.oldParentIndex = (0, _Collections.remove)(oldParent.children, shape); // add to new parent at position (0, _Collections.add)(newParent.children, shape, newParentIndex); // update shape parent + position (0, _minDash.assign)(shape, { parent: newParent, x: shape.x + delta.x, y: shape.y + delta.y }); return shape; }; MoveShapeHandler.prototype.postExecute = function (context) { var shape = context.shape, delta = context.delta, hints = context.hints; var modeling = this._modeling; if (hints.layout !== false) { (0, _minDash.forEach)(shape.incoming, function (c) { modeling.layoutConnection(c, { connectionEnd: (0, _AnchorsHelper.getMovedTargetAnchor)(c, shape, delta) }); }); (0, _minDash.forEach)(shape.outgoing, function (c) { modeling.layoutConnection(c, { connectionStart: (0, _AnchorsHelper.getMovedSourceAnchor)(c, shape, delta) }); }); } if (hints.recurse !== false) { this.moveChildren(context); } }; MoveShapeHandler.prototype.revert = function (context) { var shape = context.shape, oldParent = context.oldParent, oldParentIndex = context.oldParentIndex, delta = context.delta; // restore previous location in old parent (0, _Collections.add)(oldParent.children, shape, oldParentIndex); // revert to old position and parent (0, _minDash.assign)(shape, { parent: oldParent, x: shape.x - delta.x, y: shape.y - delta.y }); return shape; }; MoveShapeHandler.prototype.moveChildren = function (context) { var delta = context.delta, shape = context.shape; this._helper.moveRecursive(shape.children, delta, null); }; MoveShapeHandler.prototype.getNewParent = function (context) { return context.newParent || context.shape.parent; }; },{"../../../util/Collections":393,"./helper/AnchorsHelper":327,"./helper/MoveHelper":329,"min-dash":505}],319:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = PasteHandler; var _minDash = require('min-dash'); function removeProperties(element, properties) { (0, _minDash.forEach)(properties, function (prop) { if (element[prop]) { delete element[prop]; } }); } /** * A handler that implements pasting of elements onto the diagram. * * @param {eventBus} EventBus * @param {canvas} Canvas * @param {selection} Selection * @param {elementFactory} ElementFactory * @param {modeling} Modeling * @param {rules} Rules */ function PasteHandler(eventBus, canvas, selection, elementFactory, modeling, rules) { this._eventBus = eventBus; this._canvas = canvas; this._selection = selection; this._elementFactory = elementFactory; this._modeling = modeling; this._rules = rules; } PasteHandler.$inject = ['eventBus', 'canvas', 'selection', 'elementFactory', 'modeling', 'rules']; // api ////////////////////// /** * Creates a new shape * * @param {Object} context * @param {Object} context.tree the new shape * @param {Element} context.topParent the paste target */ PasteHandler.prototype.preExecute = function (context) { var eventBus = this._eventBus, self = this; var tree = context.tree, topParent = context.topParent, position = context.position; tree.createdElements = {}; tree.labels = []; (0, _minDash.forEach)(tree, function (elements, depthStr) { var depth = parseInt(depthStr, 10); if (isNaN(depth)) { return; } // set the parent on the top level elements if (!depth) { elements = (0, _minDash.map)(elements, function (descriptor) { descriptor.parent = topParent; return descriptor; }); } // Order by priority for element creation elements = (0, _minDash.sortBy)(elements, 'priority'); (0, _minDash.forEach)(elements, function (descriptor) { var id = descriptor.id, parent = descriptor.parent, hints = {}, newPosition; var element = (0, _minDash.assign)({}, descriptor); if (depth) { element.parent = self._getCreatedElement(parent, tree); } // this happens when shapes have not been created due to rules if (!parent) { return; } eventBus.fire('element.paste', { createdElements: tree.createdElements, descriptor: element }); // in case the parent changed during 'element.paste' parent = element.parent; if (element.waypoints) { element = self._createConnection(element, parent, position, tree); if (element) { tree.createdElements[id] = { element: element, descriptor: descriptor }; } return; } // supply not-root information as hint if (element.parent !== topParent) { hints.root = false; } // set host if (element.host) { hints.attach = true; parent = self._getCreatedElement(element.host, tree); } // handle labels if (element.labelTarget) { return tree.labels.push(element); } newPosition = { x: Math.round(position.x + element.delta.x + element.width / 2), y: Math.round(position.y + element.delta.y + element.height / 2) }; removeProperties(element, ['id', 'parent', 'delta', 'host', 'priority']); element = self._createShape(element, parent, newPosition, hints); if (element) { tree.createdElements[id] = { element: element, descriptor: descriptor }; } }); }); }; // move label's to their relative position PasteHandler.prototype.postExecute = function (context) { var modeling = this._modeling, selection = this._selection, self = this; var tree = context.tree, labels = tree.labels, topLevelElements = []; (0, _minDash.forEach)(labels, function (labelDescriptor) { var labelTarget = self._getCreatedElement(labelDescriptor.labelTarget, tree), labels, labelTargetPos, newPosition; if (!labelTarget) { return; } labels = labelTarget.labels; if (!labels || !labels.length) { return; } labelTargetPos = { x: labelTarget.x, y: labelTarget.y }; if (labelTarget.waypoints) { labelTargetPos = labelTarget.waypoints[0]; } (0, _minDash.forEach)(labels, function (label) { newPosition = { x: Math.round(labelTargetPos.x - label.x + labelDescriptor.delta.x), y: Math.round(labelTargetPos.y - label.y + labelDescriptor.delta.y) }; modeling.moveShape(label, newPosition, labelTarget.parent); }); }); (0, _minDash.forEach)(tree[0], function (descriptor) { var id = descriptor.id, toplevel = tree.createdElements[id]; if (toplevel) { topLevelElements.push(toplevel.element); } }); selection.select(topLevelElements); }; PasteHandler.prototype._createConnection = function (element, parent, parentCenter, tree) { var modeling = this._modeling, rules = this._rules; var connection, source, target, canPaste; element.waypoints = (0, _minDash.map)(element.waypoints, function (waypoint, idx) { return { x: Math.round(parentCenter.x + element.delta[idx].x), y: Math.round(parentCenter.y + element.delta[idx].y) }; }); source = this._getCreatedElement(element.source, tree); target = this._getCreatedElement(element.target, tree); if (!source || !target) { return null; } canPaste = rules.allowed('element.paste', { source: source, target: target }); if (!canPaste) { return null; } removeProperties(element, ['id', 'parent', 'delta', 'source', 'target', 'width', 'height', 'priority']); connection = modeling.createConnection(source, target, element, parent); return connection; }; PasteHandler.prototype._createShape = function (element, parent, position, isAttach, hints) { var modeling = this._modeling, elementFactory = this._elementFactory, rules = this._rules; var canPaste = rules.allowed('element.paste', { element: element, position: position, parent: parent }); if (!canPaste) { return null; } var shape = elementFactory.createShape(element); modeling.createShape(shape, position, parent, isAttach, hints); return shape; }; PasteHandler.prototype._getCreatedElement = function (id, tree) { return tree.createdElements[id] && tree.createdElements[id].element; }; },{"min-dash":505}],320:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ReconnectConnectionHandler; var _minDash = require('min-dash'); /** * Reconnect connection handler */ function ReconnectConnectionHandler() {} ReconnectConnectionHandler.$inject = []; ReconnectConnectionHandler.prototype.execute = function (context) { var newSource = context.newSource, newTarget = context.newTarget, connection = context.connection, dockingOrPoints = context.dockingOrPoints, oldWaypoints = connection.waypoints, newWaypoints; if (!newSource && !newTarget) { throw new Error('newSource or newTarget are required'); } if (newSource && newTarget) { throw new Error('must specify either newSource or newTarget'); } context.oldWaypoints = oldWaypoints; if ((0, _minDash.isArray)(dockingOrPoints)) { newWaypoints = dockingOrPoints; } else { newWaypoints = oldWaypoints.slice(); newWaypoints.splice(newSource ? 0 : -1, 1, dockingOrPoints); } if (newSource) { context.oldSource = connection.source; connection.source = newSource; } if (newTarget) { context.oldTarget = connection.target; connection.target = newTarget; } connection.waypoints = newWaypoints; return connection; }; ReconnectConnectionHandler.prototype.revert = function (context) { var newSource = context.newSource, newTarget = context.newTarget, connection = context.connection; if (newSource) { connection.source = context.oldSource; } if (newTarget) { connection.target = context.oldTarget; } connection.waypoints = context.oldWaypoints; return connection; }; },{"min-dash":505}],321:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ReplaceShapeHandler; var _minDash = require('min-dash'); /** * A handler that implements reversible replacing of shapes. * Internally the old shape will be removed and the new shape will be added. * * * @class * @constructor * * @param {canvas} Canvas */ function ReplaceShapeHandler(modeling, rules) { this._modeling = modeling; this._rules = rules; } ReplaceShapeHandler.$inject = ['modeling', 'rules']; // api ////////////////////// /** * Replaces a shape with an replacement Element. * * The newData object should contain type, x, y. * * If possible also the incoming/outgoing connection * will be restored. * * @param {Object} context */ ReplaceShapeHandler.prototype.preExecute = function (context) { var self = this, modeling = this._modeling, rules = this._rules; var oldShape = context.oldShape, newData = context.newData, hints = context.hints, newShape; function canReconnect(type, source, target, connection) { return rules.allowed(type, { source: source, target: target, connection: connection }); } // (1) place a new shape at the given position var position = { x: newData.x, y: newData.y }; newShape = context.newShape = context.newShape || self.createShape(newData, position, oldShape.parent, hints); // (2) update the host if (oldShape.host) { modeling.updateAttachment(newShape, oldShape.host); } // (3) adopt all children from the old shape var children; if (hints.moveChildren !== false) { children = oldShape.children.slice(); modeling.moveElements(children, { x: 0, y: 0 }, newShape); } // (4) reconnect connections to the new shape (where allowed) var incoming = oldShape.incoming.slice(), outgoing = oldShape.outgoing.slice(); (0, _minDash.forEach)(incoming, function (connection) { var waypoints = connection.waypoints, docking = waypoints[waypoints.length - 1], source = connection.source, allowed = canReconnect('connection.reconnectEnd', source, newShape, connection); if (allowed) { self.reconnectEnd(connection, newShape, docking); } }); (0, _minDash.forEach)(outgoing, function (connection) { var waypoints = connection.waypoints, docking = waypoints[0], target = connection.target, allowed = canReconnect('connection.reconnectStart', newShape, target, connection); if (allowed) { self.reconnectStart(connection, newShape, docking); } }); }; ReplaceShapeHandler.prototype.postExecute = function (context) { var modeling = this._modeling; var oldShape = context.oldShape, newShape = context.newShape; // if an element gets resized on replace, layout the connection again (0, _minDash.forEach)(newShape.incoming, function (c) { modeling.layoutConnection(c, { endChanged: true }); }); (0, _minDash.forEach)(newShape.outgoing, function (c) { modeling.layoutConnection(c, { startChanged: true }); }); modeling.removeShape(oldShape); }; ReplaceShapeHandler.prototype.execute = function (context) {}; ReplaceShapeHandler.prototype.revert = function (context) {}; ReplaceShapeHandler.prototype.createShape = function (shape, position, target, hints) { var modeling = this._modeling; return modeling.createShape(shape, position, target, hints); }; ReplaceShapeHandler.prototype.reconnectStart = function (connection, newSource, dockingPoint) { var modeling = this._modeling; modeling.reconnectStart(connection, newSource, dockingPoint); }; ReplaceShapeHandler.prototype.reconnectEnd = function (connection, newTarget, dockingPoint) { var modeling = this._modeling; modeling.reconnectEnd(connection, newTarget, dockingPoint); }; },{"min-dash":505}],322:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ResizeShapeHandler; var _minDash = require('min-dash'); var _AnchorsHelper = require('./helper/AnchorsHelper'); /** * A handler that implements reversible resizing of shapes. * * @param {Modeling} modeling */ function ResizeShapeHandler(modeling) { this._modeling = modeling; } ResizeShapeHandler.$inject = ['modeling']; /** * { * shape: {....} * newBounds: { * width: 20, * height: 40, * x: 5, * y: 10 * } * * } */ ResizeShapeHandler.prototype.execute = function (context) { var shape = context.shape, newBounds = context.newBounds, minBounds = context.minBounds; if (newBounds.x === undefined || newBounds.y === undefined || newBounds.width === undefined || newBounds.height === undefined) { throw new Error('newBounds must have {x, y, width, height} properties'); } if (minBounds && (newBounds.width < minBounds.width || newBounds.height < minBounds.height)) { throw new Error('width and height cannot be less than minimum height and width'); } else if (!minBounds && newBounds.width < 10 || newBounds.height < 10) { throw new Error('width and height cannot be less than 10px'); } // save old bbox in context context.oldBounds = { width: shape.width, height: shape.height, x: shape.x, y: shape.y }; // update shape (0, _minDash.assign)(shape, { width: newBounds.width, height: newBounds.height, x: newBounds.x, y: newBounds.y }); return shape; }; ResizeShapeHandler.prototype.postExecute = function (context) { var shape = context.shape, oldBounds = context.oldBounds; var modeling = this._modeling; (0, _minDash.forEach)(shape.incoming, function (c) { modeling.layoutConnection(c, { connectionEnd: (0, _AnchorsHelper.getResizedTargetAnchor)(c, shape, oldBounds) }); }); (0, _minDash.forEach)(shape.outgoing, function (c) { modeling.layoutConnection(c, { connectionStart: (0, _AnchorsHelper.getResizedSourceAnchor)(c, shape, oldBounds) }); }); }; ResizeShapeHandler.prototype.revert = function (context) { var shape = context.shape, oldBounds = context.oldBounds; // restore previous bbox (0, _minDash.assign)(shape, { width: oldBounds.width, height: oldBounds.height, x: oldBounds.x, y: oldBounds.y }); return shape; }; },{"./helper/AnchorsHelper":327,"min-dash":505}],323:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SpaceToolHandler; var _minDash = require('min-dash'); var _SpaceUtil = require('../../space-tool/SpaceUtil'); /** * A handler that implements reversible creating and removing of space. * * It executes in two phases: * * (1) resize all affected resizeShapes * (2) move all affected moveElements */ function SpaceToolHandler(modeling) { this._modeling = modeling; } SpaceToolHandler.$inject = ['modeling']; SpaceToolHandler.prototype.preExecute = function (context) { // resize var modeling = this._modeling, resizingShapes = context.resizingShapes, delta = context.delta, direction = context.direction; (0, _minDash.forEach)(resizingShapes, function (shape) { var newBounds = (0, _SpaceUtil.resizeBounds)(shape, direction, delta); modeling.resizeShape(shape, newBounds); }); }; SpaceToolHandler.prototype.postExecute = function (context) { // move var modeling = this._modeling, movingShapes = context.movingShapes, delta = context.delta; modeling.moveElements(movingShapes, delta, undefined, { autoResize: false, attach: false }); }; SpaceToolHandler.prototype.execute = function (context) {}; SpaceToolHandler.prototype.revert = function (context) {}; },{"../../space-tool/SpaceUtil":367,"min-dash":505}],324:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ToggleShapeCollapseHandler; /** * A handler that toggles the collapsed state of an element * and the visibility of all its children. * * @param {Modeling} modeling */ function ToggleShapeCollapseHandler(modeling) { this._modeling = modeling; } ToggleShapeCollapseHandler.$inject = ['modeling']; ToggleShapeCollapseHandler.prototype.execute = function (context) { var shape = context.shape, children = shape.children; // remember previous visibility of children context.oldChildrenVisibility = getElementsVisibility(children); // toggle state shape.collapsed = !shape.collapsed; // hide/show children setHidden(children, shape.collapsed); return [shape].concat(children); }; ToggleShapeCollapseHandler.prototype.revert = function (context) { var shape = context.shape, oldChildrenVisibility = context.oldChildrenVisibility; var children = shape.children; // set old visability of children restoreVisibility(children, oldChildrenVisibility); // retoggle state shape.collapsed = !shape.collapsed; return [shape].concat(children); }; // helpers ////////////////////// /** * Return a map { elementId -> hiddenState}. * * @param {Array} elements * * @return {Object} */ function getElementsVisibility(elements) { var result = {}; elements.forEach(function (e) { result[e.id] = e.hidden; }); return result; } function setHidden(elements, newHidden) { elements.forEach(function (element) { element.hidden = newHidden; }); } function restoreVisibility(elements, lastState) { elements.forEach(function (e) { e.hidden = lastState[e.id]; }); } },{}],325:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UpdateAttachmentHandler; var _Collections = require('../../../util/Collections'); /** * A handler that implements reversible attaching/detaching of shapes. */ function UpdateAttachmentHandler(modeling) { this._modeling = modeling; } UpdateAttachmentHandler.$inject = ['modeling']; UpdateAttachmentHandler.prototype.execute = function (context) { var shape = context.shape, newHost = context.newHost, oldHost = shape.host; // (0) detach from old host context.oldHost = oldHost; context.attacherIdx = removeAttacher(oldHost, shape); // (1) attach to new host addAttacher(newHost, shape); // (2) update host shape.host = newHost; return shape; }; UpdateAttachmentHandler.prototype.revert = function (context) { var shape = context.shape, newHost = context.newHost, oldHost = context.oldHost, attacherIdx = context.attacherIdx; // (2) update host shape.host = oldHost; // (1) attach to new host removeAttacher(newHost, shape); // (0) detach from old host addAttacher(oldHost, shape, attacherIdx); return shape; }; function removeAttacher(host, attacher) { // remove attacher from host return (0, _Collections.remove)(host && host.attachers, attacher); } function addAttacher(host, attacher, idx) { if (!host) { return; } var attachers = host.attachers; if (!attachers) { host.attachers = attachers = []; } (0, _Collections.add)(attachers, attacher, idx); } },{"../../../util/Collections":393}],326:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UpdateWaypointsHandler; function UpdateWaypointsHandler() {} UpdateWaypointsHandler.prototype.execute = function (context) { var connection = context.connection, newWaypoints = context.newWaypoints; context.oldWaypoints = connection.waypoints; connection.waypoints = newWaypoints; return connection; }; UpdateWaypointsHandler.prototype.revert = function (context) { var connection = context.connection, oldWaypoints = context.oldWaypoints; connection.waypoints = oldWaypoints; return connection; }; },{}],327:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getResizedSourceAnchor = getResizedSourceAnchor; exports.getResizedTargetAnchor = getResizedTargetAnchor; exports.getMovedSourceAnchor = getMovedSourceAnchor; exports.getMovedTargetAnchor = getMovedTargetAnchor; var _AttachUtil = require('../../../../util/AttachUtil'); function getResizedSourceAnchor(connection, shape, oldBounds) { var waypoints = safeGetWaypoints(connection), oldAnchor = waypoints[0]; return (0, _AttachUtil.getNewAttachPoint)(oldAnchor.original || oldAnchor, oldBounds, shape); } function getResizedTargetAnchor(connection, shape, oldBounds) { var waypoints = safeGetWaypoints(connection), oldAnchor = waypoints[waypoints.length - 1]; return (0, _AttachUtil.getNewAttachPoint)(oldAnchor.original || oldAnchor, oldBounds, shape); } function getMovedSourceAnchor(connection, source, moveDelta) { return getResizedSourceAnchor(connection, source, substractPosition(source, moveDelta)); } function getMovedTargetAnchor(connection, target, moveDelta) { return getResizedTargetAnchor(connection, target, substractPosition(target, moveDelta)); } // helpers ////////////////////// function substractPosition(bounds, delta) { return { x: bounds.x - delta.x, y: bounds.y - delta.y, width: bounds.width, height: bounds.height }; } /** * Return waypoints of given connection; throw if non exists (should not happen!!). * * @param {Connection} connection * * @return {Array} */ function safeGetWaypoints(connection) { var waypoints = connection.waypoints; if (!waypoints.length) { throw new Error('connection#' + connection.id + ': no waypoints'); } return waypoints; } },{"../../../../util/AttachUtil":391}],328:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MoveClosure; var _minDash = require('min-dash'); var _Elements = require('../../../../util/Elements'); function MoveClosure() { this.allShapes = {}; this.allConnections = {}; this.enclosedElements = {}; this.enclosedConnections = {}; this.topLevel = {}; } MoveClosure.prototype.add = function (element, isTopLevel) { return this.addAll([element], isTopLevel); }; MoveClosure.prototype.addAll = function (elements, isTopLevel) { var newClosure = (0, _Elements.getClosure)(elements, !!isTopLevel, this); (0, _minDash.assign)(this, newClosure); return this; }; },{"../../../../util/Elements":396,"min-dash":505}],329:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MoveHelper; var _minDash = require('min-dash'); var _AnchorsHelper = require('./AnchorsHelper'); var _MoveClosure = require('./MoveClosure'); var _MoveClosure2 = _interopRequireDefault(_MoveClosure); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A helper that is able to carry out serialized move * operations on multiple elements. * * @param {Modeling} modeling */ function MoveHelper(modeling) { this._modeling = modeling; } /** * Move the specified elements and all children by the given delta. * * This moves all enclosed connections, too and layouts all affected * external connections. * * @param {Array} elements * @param {Point} delta * @param {djs.model.Base} newParent applied to the first level of shapes * * @return {Array} list of touched elements */ MoveHelper.prototype.moveRecursive = function (elements, delta, newParent) { if (!elements) { return []; } else { return this.moveClosure(this.getClosure(elements), delta, newParent); } }; /** * Move the given closure of elmements. * * @param {Object} closure * @param {Point} delta * @param {djs.model.Base} [newParent] * @param {djs.model.Base} [newHost] */ MoveHelper.prototype.moveClosure = function (closure, delta, newParent, newHost, primaryShape) { var modeling = this._modeling; var allShapes = closure.allShapes, allConnections = closure.allConnections, enclosedConnections = closure.enclosedConnections, topLevel = closure.topLevel, keepParent = false; if (primaryShape && primaryShape.parent === newParent) { keepParent = true; } // move all shapes (0, _minDash.forEach)(allShapes, function (shape) { // move the element according to the given delta modeling.moveShape(shape, delta, topLevel[shape.id] && !keepParent && newParent, { recurse: false, layout: false }); }); // move all child connections / layout external connections (0, _minDash.forEach)(allConnections, function (c) { var sourceMoved = !!allShapes[c.source.id], targetMoved = !!allShapes[c.target.id]; if (enclosedConnections[c.id] && sourceMoved && targetMoved) { modeling.moveConnection(c, delta, topLevel[c.id] && !keepParent && newParent); } else { modeling.layoutConnection(c, { connectionStart: sourceMoved && (0, _AnchorsHelper.getMovedSourceAnchor)(c, c.source, delta), connectionEnd: targetMoved && (0, _AnchorsHelper.getMovedTargetAnchor)(c, c.target, delta) }); } }); }; /** * Returns the closure for the selected elements * * @param {Array} elements * @return {MoveClosure} closure */ MoveHelper.prototype.getClosure = function (elements) { return new _MoveClosure2.default().addAll(elements, true); }; },{"./AnchorsHelper":327,"./MoveClosure":328,"min-dash":505}],330:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MouseTracking; var _minDash = require('min-dash'); function MouseTracking(eventBus, canvas) { this._eventBus = eventBus; this._canvas = canvas; this._init(); } MouseTracking.$inject = ['eventBus', 'canvas']; MouseTracking.prototype.getHoverContext = function () { var viewbox = this._canvas.viewbox(); return { element: this._hoverElement, point: { x: viewbox.x + Math.round(this._mouseX / viewbox.scale), y: viewbox.y + Math.round(this._mouseY / viewbox.scale) } }; }; MouseTracking.prototype._init = function () { var eventBus = this._eventBus, canvas = this._canvas; var container = canvas.getContainer(); this._setMousePosition = (0, _minDash.bind)(this._setMousePosition, this); container.addEventListener('mousemove', this._setMousePosition); eventBus.on('diagram.destroy', function () { container.removeEventListener('mousemove', this._setMousePosition); }, this); eventBus.on('element.hover', this._setHoverElement, this); }; MouseTracking.prototype._setHoverElement = function (event) { this._hoverElement = event.element; }; MouseTracking.prototype._setMousePosition = function (event) { this._mouseX = event.layerX; this._mouseY = event.layerY; }; },{"min-dash":505}],331:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _MouseTracking = require('./MouseTracking'); var _MouseTracking2 = _interopRequireDefault(_MouseTracking); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['mouseTracking'], mouseTracking: ['type', _MouseTracking2.default] }; },{"./MouseTracking":330}],332:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MoveEvents; var _minDash = require('min-dash'); var _Event = require('../../util/Event'); var LOW_PRIORITY = 500, MEDIUM_PRIORITY = 1250, HIGH_PRIORITY = 1500; var round = Math.round; function mid(element) { return { x: element.x + round(element.width / 2), y: element.y + round(element.height / 2) }; } /** * A plugin that makes shapes draggable / droppable. * * @param {EventBus} eventBus * @param {Dragging} dragging * @param {Modeling} modeling * @param {Selection} selection * @param {Rules} rules */ function MoveEvents(eventBus, dragging, modeling, selection, rules) { // rules function canMove(shapes, delta, position, target) { return rules.allowed('elements.move', { shapes: shapes, delta: delta, position: position, target: target }); } // move events // assign a high priority to this handler to setup the environment // others may hook up later, e.g. at default priority and modify // the move environment. // // This sets up the context with // // * shape: the primary shape being moved // * shapes: a list of shapes to be moved // * validatedShapes: a list of shapes that are being checked // against the rules before and during move // eventBus.on('shape.move.start', HIGH_PRIORITY, function (event) { var context = event.context, shape = event.shape, shapes = selection.get().slice(); // move only single shape if the dragged element // is not part of the current selection if (shapes.indexOf(shape) === -1) { shapes = [shape]; } // ensure we remove nested elements in the collection // and add attachers for a proper dragger shapes = removeNested(shapes); // attach shapes to drag context (0, _minDash.assign)(context, { shapes: shapes, validatedShapes: shapes, shape: shape }); }); // assign a high priority to this handler to setup the environment // others may hook up later, e.g. at default priority and modify // the move environment // eventBus.on('shape.move.start', MEDIUM_PRIORITY, function (event) { var context = event.context, validatedShapes = context.validatedShapes, canExecute; canExecute = context.canExecute = canMove(validatedShapes); // check if we can move the elements if (!canExecute) { return false; } }); // assign a low priority to this handler // to let others modify the move event before we update // the context // eventBus.on('shape.move.move', LOW_PRIORITY, function (event) { var context = event.context, validatedShapes = context.validatedShapes, hover = event.hover, delta = { x: event.dx, y: event.dy }, position = { x: event.x, y: event.y }, canExecute; // check if we can move the elements canExecute = canMove(validatedShapes, delta, position, hover); context.delta = delta; context.canExecute = canExecute; // simply ignore move over if (canExecute === null) { context.target = null; return; } context.target = hover; }); eventBus.on('shape.move.end', function (event) { var context = event.context; var delta = context.delta, canExecute = context.canExecute, isAttach = canExecute === 'attach', shapes = context.shapes; if (!canExecute) { return false; } // ensure we have actual pixel values deltas // (important when zoom level was > 1 during move) delta.x = round(delta.x); delta.y = round(delta.y); modeling.moveElements(shapes, delta, context.target, { primaryShape: context.shape, attach: isAttach }); }); // move activation eventBus.on('element.mousedown', function (event) { var originalEvent = (0, _Event.getOriginal)(event); if (!originalEvent) { throw new Error('must supply DOM mousedown event'); } return start(originalEvent, event.element); }); function start(event, element, activate) { // do not move connections or the root element if (element.waypoints || !element.parent) { return; } var referencePoint = mid(element); dragging.init(event, referencePoint, 'shape.move', { cursor: 'grabbing', autoActivate: activate, data: { shape: element, context: {} } }); // we've handled the event return true; } // API this.start = start; } MoveEvents.$inject = ['eventBus', 'dragging', 'modeling', 'selection', 'rules']; /** * Return a filtered list of elements that do not contain * those nested into others. * * @param {Array} elements * * @return {Array} filtered */ function removeNested(elements) { var ids = (0, _minDash.groupBy)(elements, 'id'); return (0, _minDash.filter)(elements, function (element) { while (element = element.parent) { // parent in selection if (ids[element.id]) { return false; } } return true; }); } },{"../../util/Event":397,"min-dash":505}],333:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MovePreview; var _minDash = require('min-dash'); var _Elements = require('../../util/Elements'); var _tinySvg = require('tiny-svg'); var _SvgTransformUtil = require('../../util/SvgTransformUtil'); var LOW_PRIORITY = 499; var MARKER_DRAGGING = 'djs-dragging', MARKER_OK = 'drop-ok', MARKER_NOT_OK = 'drop-not-ok', MARKER_NEW_PARENT = 'new-parent', MARKER_ATTACH = 'attach-ok'; /** * Provides previews for moving shapes when moving. * * @param {EventBus} eventBus * @param {ElementRegistry} elementRegistry * @param {Canvas} canvas * @param {Styles} styles */ function MovePreview(eventBus, elementRegistry, canvas, styles, previewSupport) { function getVisualDragShapes(shapes) { var elements = getAllDraggedElements(shapes); var filteredElements = removeEdges(elements); return filteredElements; } function getAllDraggedElements(shapes) { var allShapes = (0, _Elements.selfAndAllChildren)(shapes, true); var allConnections = (0, _minDash.map)(allShapes, function (shape) { return (shape.incoming || []).concat(shape.outgoing || []); }); return (0, _minDash.flatten)(allShapes.concat(allConnections)); } /** * Sets drop marker on an element. */ function setMarker(element, marker) { [MARKER_ATTACH, MARKER_OK, MARKER_NOT_OK, MARKER_NEW_PARENT].forEach(function (m) { if (m === marker) { canvas.addMarker(element, m); } else { canvas.removeMarker(element, m); } }); } /** * Make an element draggable. * * @param {Object} context * @param {djs.model.Base} element * @param {Boolean} addMarker */ function makeDraggable(context, element, addMarker) { previewSupport.addDragger(element, context.dragGroup); if (addMarker) { canvas.addMarker(element, MARKER_DRAGGING); } if (context.allDraggedElements) { context.allDraggedElements.push(element); } else { context.allDraggedElements = [element]; } } // assign a low priority to this handler // to let others modify the move context before // we draw things eventBus.on('shape.move.start', LOW_PRIORITY, function (event) { var context = event.context, dragShapes = context.shapes, allDraggedElements = context.allDraggedElements; var visuallyDraggedShapes = getVisualDragShapes(dragShapes); if (!context.dragGroup) { var dragGroup = (0, _tinySvg.create)('g'); (0, _tinySvg.attr)(dragGroup, styles.cls('djs-drag-group', ['no-events'])); var defaultLayer = canvas.getDefaultLayer(); (0, _tinySvg.append)(defaultLayer, dragGroup); context.dragGroup = dragGroup; } // add previews visuallyDraggedShapes.forEach(function (shape) { previewSupport.addDragger(shape, context.dragGroup); }); // cache all dragged elements / gfx // so that we can quickly undo their state changes later if (!allDraggedElements) { allDraggedElements = getAllDraggedElements(dragShapes); } else { allDraggedElements = (0, _minDash.flatten)([allDraggedElements, getAllDraggedElements(dragShapes)]); } // add dragging marker (0, _minDash.forEach)(allDraggedElements, function (e) { canvas.addMarker(e, MARKER_DRAGGING); }); context.allDraggedElements = allDraggedElements; // determine, if any of the dragged elements have different parents context.differentParents = haveDifferentParents(dragShapes); }); // update previews eventBus.on('shape.move.move', LOW_PRIORITY, function (event) { var context = event.context, dragGroup = context.dragGroup, target = context.target, parent = context.shape.parent, canExecute = context.canExecute; if (target) { if (canExecute === 'attach') { setMarker(target, MARKER_ATTACH); } else if (context.canExecute && target && target.id !== parent.id) { setMarker(target, MARKER_NEW_PARENT); } else { setMarker(target, context.canExecute ? MARKER_OK : MARKER_NOT_OK); } } (0, _SvgTransformUtil.translate)(dragGroup, event.dx, event.dy); }); eventBus.on(['shape.move.out', 'shape.move.cleanup'], function (event) { var context = event.context, target = context.target; if (target) { setMarker(target, null); } }); // remove previews eventBus.on('shape.move.cleanup', function (event) { var context = event.context, allDraggedElements = context.allDraggedElements, dragGroup = context.dragGroup; // remove dragging marker (0, _minDash.forEach)(allDraggedElements, function (e) { canvas.removeMarker(e, MARKER_DRAGGING); }); if (dragGroup) { (0, _tinySvg.clear)(dragGroup); } }); // API ////////////////////// /** * Make an element draggable. * * @param {Object} context * @param {djs.model.Base} element * @param {Boolean} addMarker */ this.makeDraggable = makeDraggable; } MovePreview.$inject = ['eventBus', 'elementRegistry', 'canvas', 'styles', 'previewSupport']; // helpers ////////////////////// /** * returns elements minus all connections * where source or target is not elements */ function removeEdges(elements) { var filteredElements = (0, _minDash.filter)(elements, function (element) { if (!isConnection(element)) { return true; } else { return (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.source.id })) && (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.target.id })); } }); return filteredElements; } function haveDifferentParents(elements) { return (0, _minDash.size)((0, _minDash.groupBy)(elements, function (e) { return e.parent && e.parent.id; })) !== 1; } /** * Checks if an element is a connection. */ function isConnection(element) { return element.waypoints; } },{"../../util/Elements":396,"../../util/SvgTransformUtil":408,"min-dash":505,"tiny-svg":535}],334:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _interactionEvents = require('../interaction-events'); var _interactionEvents2 = _interopRequireDefault(_interactionEvents); var _selection = require('../selection'); var _selection2 = _interopRequireDefault(_selection); var _outline = require('../outline'); var _outline2 = _interopRequireDefault(_outline); var _rules = require('../rules'); var _rules2 = _interopRequireDefault(_rules); var _dragging = require('../dragging'); var _dragging2 = _interopRequireDefault(_dragging); var _previewSupport = require('../preview-support'); var _previewSupport2 = _interopRequireDefault(_previewSupport); var _Move = require('./Move'); var _Move2 = _interopRequireDefault(_Move); var _MovePreview = require('./MovePreview'); var _MovePreview2 = _interopRequireDefault(_MovePreview); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_interactionEvents2.default, _selection2.default, _outline2.default, _rules2.default, _dragging2.default, _previewSupport2.default], __init__: ['move', 'movePreview'], move: ['type', _Move2.default], movePreview: ['type', _MovePreview2.default] }; },{"../dragging":286,"../interaction-events":294,"../outline":337,"../preview-support":345,"../rules":355,"../selection":361,"./Move":332,"./MovePreview":333}],335:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = OrderingProvider; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CommandInterceptor = require('../../command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * An abstract provider that allows modelers to implement a custom * ordering of diagram elements on the canvas. * * It makes sure that the order is always preserved during element * creation and move operations. * * In order to use this behavior, inherit from it and override * the method {@link OrderingProvider#getOrdering}. * * @example * * ```javascript * function CustomOrderingProvider(eventBus) { * OrderingProvider.call(this, eventBus); * * this.getOrdering = function(element, newParent) { * // always insert elements at the front * // when moving * return { * index: 0, * parent: newParent * }; * }; * } * ``` * * @param {EventBus} eventBus */ function OrderingProvider(eventBus) { _CommandInterceptor2.default.call(this, eventBus); var self = this; this.preExecute(['shape.create', 'connection.create'], function (event) { var context = event.context, element = context.shape || context.connection, parent = context.parent; var ordering = self.getOrdering(element, parent); if (ordering) { if (ordering.parent !== undefined) { context.parent = ordering.parent; } context.parentIndex = ordering.index; } }); this.preExecute(['shape.move', 'connection.move'], function (event) { var context = event.context, element = context.shape || context.connection, parent = context.newParent || element.parent; var ordering = self.getOrdering(element, parent); if (ordering) { if (ordering.parent !== undefined) { context.newParent = ordering.parent; } context.newParentIndex = ordering.index; } }); } /** * Return a custom ordering of the element, both in terms * of parent element and index in the new parent. * * Implementors of this method must return an object with * `parent` _and_ `index` in it. * * @param {djs.model.Base} element * @param {djs.model.Shape} newParent * * @return {Object} ordering descriptor */ OrderingProvider.prototype.getOrdering = function (element, newParent) { return null; }; (0, _inherits2.default)(OrderingProvider, _CommandInterceptor2.default); },{"../../command/CommandInterceptor":243,"inherits":415}],336:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Outline; var _Elements = require('../../util/Elements'); var _tinySvg = require('tiny-svg'); var _minDom = require('min-dom'); var _minDash = require('min-dash'); var LOW_PRIORITY = 500; /** * @class * * A plugin that adds an outline to shapes and connections that may be activated and styled * via CSS classes. * * @param {EventBus} eventBus * @param {Styles} styles * @param {ElementRegistry} elementRegistry */ function Outline(eventBus, styles, elementRegistry) { this.offset = 6; var OUTLINE_STYLE = styles.cls('djs-outline', ['no-fill']); var self = this; function createOutline(gfx, bounds) { var outline = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(outline, (0, _minDash.assign)({ x: 10, y: 10, width: 100, height: 100 }, OUTLINE_STYLE)); (0, _tinySvg.append)(gfx, outline); return outline; } // A low priortity is necessary, because outlines of labels have to be updated // after the label bounds have been updated in the renderer. eventBus.on(['shape.added', 'shape.changed'], LOW_PRIORITY, function (event) { var element = event.element, gfx = event.gfx; var outline = (0, _minDom.query)('.djs-outline', gfx); if (!outline) { outline = createOutline(gfx, element); } self.updateShapeOutline(outline, element); }); eventBus.on(['connection.added', 'connection.changed'], function (event) { var element = event.element, gfx = event.gfx; var outline = (0, _minDom.query)('.djs-outline', gfx); if (!outline) { outline = createOutline(gfx, element); } self.updateConnectionOutline(outline, element); }); } /** * Updates the outline of a shape respecting the dimension of the * element and an outline offset. * * @param {SVGElement} outline * @param {djs.model.Base} element */ Outline.prototype.updateShapeOutline = function (outline, element) { (0, _tinySvg.attr)(outline, { x: -this.offset, y: -this.offset, width: element.width + this.offset * 2, height: element.height + this.offset * 2 }); }; /** * Updates the outline of a connection respecting the bounding box of * the connection and an outline offset. * * @param {SVGElement} outline * @param {djs.model.Base} element */ Outline.prototype.updateConnectionOutline = function (outline, connection) { var bbox = (0, _Elements.getBBox)(connection); (0, _tinySvg.attr)(outline, { x: bbox.x - this.offset, y: bbox.y - this.offset, width: bbox.width + this.offset * 2, height: bbox.height + this.offset * 2 }); }; Outline.$inject = ['eventBus', 'styles', 'elementRegistry']; },{"../../util/Elements":396,"min-dash":505,"min-dom":506,"tiny-svg":535}],337:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _Outline = require('./Outline'); var _Outline2 = _interopRequireDefault(_Outline); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['outline'], outline: ['type', _Outline2.default] }; },{"./Outline":336}],338:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Overlays; var _minDash = require('min-dash'); var _minDom = require('min-dom'); var _Elements = require('../../util/Elements'); var _IdGenerator = require('../../util/IdGenerator'); var _IdGenerator2 = _interopRequireDefault(_IdGenerator); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // document wide unique overlay ids var ids = new _IdGenerator2.default('ov'); var LOW_PRIORITY = 500; /** * A service that allows users to attach overlays to diagram elements. * * The overlay service will take care of overlay positioning during updates. * * @example * * // add a pink badge on the top left of the shape * overlays.add(someShape, { * position: { * top: -5, * left: -5 * }, * html: '
0
' * }); * * // or add via shape id * * overlays.add('some-element-id', { * position: { * top: -5, * left: -5 * } * html: '
0
' * }); * * // or add with optional type * * overlays.add(someShape, 'badge', { * position: { * top: -5, * left: -5 * } * html: '
0
' * }); * * * // remove an overlay * * var id = overlays.add(...); * overlays.remove(id); * * * You may configure overlay defaults during tool by providing a `config` module * with `overlays.defaults` as an entry: * * { * overlays: { * defaults: { * show: { * minZoom: 0.7, * maxZoom: 5.0 * }, * scale: { * min: 1 * } * } * } * * @param {Object} config * @param {EventBus} eventBus * @param {Canvas} canvas * @param {ElementRegistry} elementRegistry */ function Overlays(config, eventBus, canvas, elementRegistry) { this._eventBus = eventBus; this._canvas = canvas; this._elementRegistry = elementRegistry; this._ids = ids; this._overlayDefaults = (0, _minDash.assign)({ // no show constraints show: null, // always scale scale: true }, config && config.defaults); /** * Mapping overlayId -> overlay */ this._overlays = {}; /** * Mapping elementId -> overlay container */ this._overlayContainers = []; // root html element for all overlays this._overlayRoot = createRoot(canvas.getContainer()); this._init(); } Overlays.$inject = ['config.overlays', 'eventBus', 'canvas', 'elementRegistry']; /** * Returns the overlay with the specified id or a list of overlays * for an element with a given type. * * @example * * // return the single overlay with the given id * overlays.get('some-id'); * * // return all overlays for the shape * overlays.get({ element: someShape }); * * // return all overlays on shape with type 'badge' * overlays.get({ element: someShape, type: 'badge' }); * * // shape can also be specified as id * overlays.get({ element: 'element-id', type: 'badge' }); * * * @param {Object} search * @param {String} [search.id] * @param {String|djs.model.Base} [search.element] * @param {String} [search.type] * * @return {Object|Array} the overlay(s) */ Overlays.prototype.get = function (search) { if ((0, _minDash.isString)(search)) { search = { id: search }; } if ((0, _minDash.isString)(search.element)) { search.element = this._elementRegistry.get(search.element); } if (search.element) { var container = this._getOverlayContainer(search.element, true); // return a list of overlays when searching by element (+type) if (container) { return search.type ? (0, _minDash.filter)(container.overlays, (0, _minDash.matchPattern)({ type: search.type })) : container.overlays.slice(); } else { return []; } } else if (search.type) { return (0, _minDash.filter)(this._overlays, (0, _minDash.matchPattern)({ type: search.type })); } else { // return single element when searching by id return search.id ? this._overlays[search.id] : null; } }; /** * Adds a HTML overlay to an element. * * @param {String|djs.model.Base} element attach overlay to this shape * @param {String} [type] optional type to assign to the overlay * @param {Object} overlay the overlay configuration * * @param {String|DOMElement} overlay.html html element to use as an overlay * @param {Object} [overlay.show] show configuration * @param {Number} [overlay.show.minZoom] minimal zoom level to show the overlay * @param {Number} [overlay.show.maxZoom] maximum zoom level to show the overlay * @param {Object} overlay.position where to attach the overlay * @param {Number} [overlay.position.left] relative to element bbox left attachment * @param {Number} [overlay.position.top] relative to element bbox top attachment * @param {Number} [overlay.position.bottom] relative to element bbox bottom attachment * @param {Number} [overlay.position.right] relative to element bbox right attachment * @param {Boolean|Object} [overlay.scale=true] false to preserve the same size regardless of * diagram zoom * @param {Number} [overlay.scale.min] * @param {Number} [overlay.scale.max] * * @return {String} id that may be used to reference the overlay for update or removal */ Overlays.prototype.add = function (element, type, overlay) { if ((0, _minDash.isObject)(type)) { overlay = type; type = null; } if (!element.id) { element = this._elementRegistry.get(element); } if (!overlay.position) { throw new Error('must specifiy overlay position'); } if (!overlay.html) { throw new Error('must specifiy overlay html'); } if (!element) { throw new Error('invalid element specified'); } var id = this._ids.next(); overlay = (0, _minDash.assign)({}, this._overlayDefaults, overlay, { id: id, type: type, element: element, html: overlay.html }); this._addOverlay(overlay); return id; }; /** * Remove an overlay with the given id or all overlays matching the given filter. * * @see Overlays#get for filter options. * * @param {String} [id] * @param {Object} [filter] */ Overlays.prototype.remove = function (filter) { var overlays = this.get(filter) || []; if (!(0, _minDash.isArray)(overlays)) { overlays = [overlays]; } var self = this; (0, _minDash.forEach)(overlays, function (overlay) { var container = self._getOverlayContainer(overlay.element, true); if (overlay) { (0, _minDom.remove)(overlay.html); (0, _minDom.remove)(overlay.htmlContainer); delete overlay.htmlContainer; delete overlay.element; delete self._overlays[overlay.id]; } if (container) { var idx = container.overlays.indexOf(overlay); if (idx !== -1) { container.overlays.splice(idx, 1); } } }); }; Overlays.prototype.show = function () { setVisible(this._overlayRoot); }; Overlays.prototype.hide = function () { setVisible(this._overlayRoot, false); }; Overlays.prototype.clear = function () { this._overlays = {}; this._overlayContainers = []; (0, _minDom.clear)(this._overlayRoot); }; Overlays.prototype._updateOverlayContainer = function (container) { var element = container.element, html = container.html; // update container left,top according to the elements x,y coordinates // this ensures we can attach child elements relative to this container var x = element.x, y = element.y; if (element.waypoints) { var bbox = (0, _Elements.getBBox)(element); x = bbox.x; y = bbox.y; } setPosition(html, x, y); (0, _minDom.attr)(container.html, 'data-container-id', element.id); }; Overlays.prototype._updateOverlay = function (overlay) { var position = overlay.position, htmlContainer = overlay.htmlContainer, element = overlay.element; // update overlay html relative to shape because // it is already positioned on the element // update relative var left = position.left, top = position.top; if (position.right !== undefined) { var width; if (element.waypoints) { width = (0, _Elements.getBBox)(element).width; } else { width = element.width; } left = position.right * -1 + width; } if (position.bottom !== undefined) { var height; if (element.waypoints) { height = (0, _Elements.getBBox)(element).height; } else { height = element.height; } top = position.bottom * -1 + height; } setPosition(htmlContainer, left || 0, top || 0); }; Overlays.prototype._createOverlayContainer = function (element) { var html = (0, _minDom.domify)('
'); this._overlayRoot.appendChild(html); var container = { html: html, element: element, overlays: [] }; this._updateOverlayContainer(container); this._overlayContainers.push(container); return container; }; Overlays.prototype._updateRoot = function (viewbox) { var scale = viewbox.scale || 1; var matrix = 'matrix(' + [scale, 0, 0, scale, -1 * viewbox.x * scale, -1 * viewbox.y * scale].join(',') + ')'; setTransform(this._overlayRoot, matrix); }; Overlays.prototype._getOverlayContainer = function (element, raw) { var container = (0, _minDash.find)(this._overlayContainers, function (c) { return c.element === element; }); if (!container && !raw) { return this._createOverlayContainer(element); } return container; }; Overlays.prototype._addOverlay = function (overlay) { var id = overlay.id, element = overlay.element, html = overlay.html, htmlContainer, overlayContainer; // unwrap jquery (for those who need it) if (html.get && html.constructor.prototype.jquery) { html = html.get(0); } // create proper html elements from // overlay HTML strings if ((0, _minDash.isString)(html)) { html = (0, _minDom.domify)(html); } overlayContainer = this._getOverlayContainer(element); htmlContainer = (0, _minDom.domify)('
'); htmlContainer.appendChild(html); if (overlay.type) { (0, _minDom.classes)(htmlContainer).add('djs-overlay-' + overlay.type); } overlay.htmlContainer = htmlContainer; overlayContainer.overlays.push(overlay); overlayContainer.html.appendChild(htmlContainer); this._overlays[id] = overlay; this._updateOverlay(overlay); this._updateOverlayVisibilty(overlay, this._canvas.viewbox()); }; Overlays.prototype._updateOverlayVisibilty = function (overlay, viewbox) { var show = overlay.show, minZoom = show && show.minZoom, maxZoom = show && show.maxZoom, htmlContainer = overlay.htmlContainer, visible = true; if (show) { if ((0, _minDash.isDefined)(minZoom) && minZoom > viewbox.scale || (0, _minDash.isDefined)(maxZoom) && maxZoom < viewbox.scale) { visible = false; } setVisible(htmlContainer, visible); } this._updateOverlayScale(overlay, viewbox); }; Overlays.prototype._updateOverlayScale = function (overlay, viewbox) { var shouldScale = overlay.scale, minScale, maxScale, htmlContainer = overlay.htmlContainer; var scale, transform = ''; if (shouldScale !== true) { if (shouldScale === false) { minScale = 1; maxScale = 1; } else { minScale = shouldScale.min; maxScale = shouldScale.max; } if ((0, _minDash.isDefined)(minScale) && viewbox.scale < minScale) { scale = (1 / viewbox.scale || 1) * minScale; } if ((0, _minDash.isDefined)(maxScale) && viewbox.scale > maxScale) { scale = (1 / viewbox.scale || 1) * maxScale; } } if ((0, _minDash.isDefined)(scale)) { transform = 'scale(' + scale + ',' + scale + ')'; } setTransform(htmlContainer, transform); }; Overlays.prototype._updateOverlaysVisibilty = function (viewbox) { var self = this; (0, _minDash.forEach)(this._overlays, function (overlay) { self._updateOverlayVisibilty(overlay, viewbox); }); }; Overlays.prototype._init = function () { var eventBus = this._eventBus; var self = this; // scroll/zoom integration function updateViewbox(viewbox) { self._updateRoot(viewbox); self._updateOverlaysVisibilty(viewbox); self.show(); } eventBus.on('canvas.viewbox.changing', function (event) { self.hide(); }); eventBus.on('canvas.viewbox.changed', function (event) { updateViewbox(event.viewbox); }); // remove integration eventBus.on(['shape.remove', 'connection.remove'], function (e) { var element = e.element; var overlays = self.get({ element: element }); (0, _minDash.forEach)(overlays, function (o) { self.remove(o.id); }); var container = self._getOverlayContainer(element); if (container) { (0, _minDom.remove)(container.html); var i = self._overlayContainers.indexOf(container); if (i !== -1) { self._overlayContainers.splice(i, 1); } } }); // move integration eventBus.on('element.changed', LOW_PRIORITY, function (e) { var element = e.element; var container = self._getOverlayContainer(element, true); if (container) { (0, _minDash.forEach)(container.overlays, function (overlay) { self._updateOverlay(overlay); }); self._updateOverlayContainer(container); } }); // marker integration, simply add them on the overlays as classes, too. eventBus.on('element.marker.update', function (e) { var container = self._getOverlayContainer(e.element, true); if (container) { (0, _minDom.classes)(container.html)[e.add ? 'add' : 'remove'](e.marker); } }); // clear overlays with diagram eventBus.on('diagram.clear', this.clear, this); }; // helpers ///////////////////////////// function createRoot(parentNode) { var root = (0, _minDom.domify)('
'); parentNode.insertBefore(root, parentNode.firstChild); return root; } function setPosition(el, x, y) { (0, _minDash.assign)(el.style, { left: x + 'px', top: y + 'px' }); } function setVisible(el, visible) { el.style.display = visible === false ? 'none' : ''; } function setTransform(el, transform) { el.style['transform-origin'] = 'top left'; ['', '-ms-', '-webkit-'].forEach(function (prefix) { el.style[prefix + 'transform'] = transform; }); } },{"../../util/Elements":396,"../../util/IdGenerator":400,"min-dash":505,"min-dom":506}],339:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _Overlays = require('./Overlays'); var _Overlays2 = _interopRequireDefault(_Overlays); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['overlays'], overlays: ['type', _Overlays2.default] }; },{"./Overlays":338}],340:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Palette; var _minDash = require('min-dash'); var _minDom = require('min-dom'); var TOGGLE_SELECTOR = '.djs-palette-toggle', ENTRY_SELECTOR = '.entry', ELEMENT_SELECTOR = TOGGLE_SELECTOR + ', ' + ENTRY_SELECTOR; var PALETTE_OPEN_CLS = 'open', PALETTE_TWO_COLUMN_CLS = 'two-column'; /** * A palette containing modeling elements. */ function Palette(eventBus, canvas) { this._eventBus = eventBus; this._canvas = canvas; this._providers = []; var self = this; eventBus.on('tool-manager.update', function (event) { var tool = event.tool; self.updateToolHighlight(tool); }); eventBus.on('i18n.changed', function () { self._update(); }); eventBus.on('diagram.init', function () { self._diagramInitialized = true; // initialize + update once diagram is ready if (self._providers.length) { self._init(); self._update(); } }); } Palette.$inject = ['eventBus', 'canvas']; /** * Register a provider with the palette * * @param {PaletteProvider} provider */ Palette.prototype.registerProvider = function (provider) { this._providers.push(provider); // postpone init / update until diagram is initialized if (!this._diagramInitialized) { return; } if (!this._container) { this._init(); } this._update(); }; /** * Returns the palette entries for a given element * * @return {Array} list of entries */ Palette.prototype.getEntries = function () { var entries = {}; // loop through all providers and their entries. // group entries by id so that overriding an entry is possible (0, _minDash.forEach)(this._providers, function (provider) { var e = provider.getPaletteEntries(); (0, _minDash.forEach)(e, function (entry, id) { entries[id] = entry; }); }); return entries; }; /** * Initialize */ Palette.prototype._init = function () { var canvas = this._canvas, eventBus = this._eventBus; var parent = canvas.getContainer(), container = this._container = (0, _minDom.domify)(Palette.HTML_MARKUP), self = this; parent.appendChild(container); _minDom.delegate.bind(container, ELEMENT_SELECTOR, 'click', function (event) { var target = event.delegateTarget; if ((0, _minDom.matches)(target, TOGGLE_SELECTOR)) { return self.toggle(); } self.trigger('click', event); }); // prevent drag propagation _minDom.event.bind(container, 'mousedown', function (event) { event.stopPropagation(); }); // prevent drag propagation _minDom.delegate.bind(container, ENTRY_SELECTOR, 'dragstart', function (event) { self.trigger('dragstart', event); }); eventBus.on('canvas.resized', this._layoutChanged, this); eventBus.fire('palette.create', { container: container }); }; /** * Update palette state. * * @param {Object} [state] { open, twoColumn } */ Palette.prototype._toggleState = function (state) { state = state || {}; var parent = this._getParentContainer(), container = this._container; var eventBus = this._eventBus; var twoColumn; var cls = (0, _minDom.classes)(container); if ('twoColumn' in state) { twoColumn = state.twoColumn; } else { twoColumn = this._needsCollapse(parent.clientHeight, this._entries || {}); } // always update two column cls.toggle(PALETTE_TWO_COLUMN_CLS, twoColumn); if ('open' in state) { cls.toggle(PALETTE_OPEN_CLS, state.open); } eventBus.fire('palette.changed', { twoColumn: twoColumn, open: this.isOpen() }); }; Palette.prototype._update = function () { var entriesContainer = (0, _minDom.query)('.djs-palette-entries', this._container), entries = this._entries = this.getEntries(); (0, _minDom.clear)(entriesContainer); (0, _minDash.forEach)(entries, function (entry, id) { var grouping = entry.group || 'default'; var container = (0, _minDom.query)('[data-group=' + grouping + ']', entriesContainer); if (!container) { container = (0, _minDom.domify)('
'); entriesContainer.appendChild(container); } var html = entry.html || (entry.separator ? '
' : '
'); var control = (0, _minDom.domify)(html); container.appendChild(control); if (!entry.separator) { (0, _minDom.attr)(control, 'data-action', id); if (entry.title) { (0, _minDom.attr)(control, 'title', entry.title); } if (entry.className) { addClasses(control, entry.className); } if (entry.imageUrl) { control.appendChild((0, _minDom.domify)('')); } } }); // open after update this.open(); }; /** * Trigger an action available on the palette * * @param {String} action * @param {Event} event */ Palette.prototype.trigger = function (action, event, autoActivate) { var entries = this._entries, entry, handler, originalEvent, button = event.delegateTarget || event.target; if (!button) { return event.preventDefault(); } entry = entries[(0, _minDom.attr)(button, 'data-action')]; // when user clicks on the palette and not on an action if (!entry) { return; } handler = entry.action; originalEvent = event.originalEvent || event; // simple action (via callback function) if ((0, _minDash.isFunction)(handler)) { if (action === 'click') { handler(originalEvent, autoActivate); } } else { if (handler[action]) { handler[action](originalEvent, autoActivate); } } // silence other actions event.preventDefault(); }; Palette.prototype._layoutChanged = function () { this._toggleState({}); }; /** * Do we need to collapse to two columns? * * @param {Number} availableHeight * @param {Object} entries * * @return {Boolean} */ Palette.prototype._needsCollapse = function (availableHeight, entries) { // top margin + bottom toggle + bottom margin // implementors must override this method if they // change the palette styles var margin = 20 + 10 + 20; var entriesHeight = Object.keys(entries).length * 46; return availableHeight < entriesHeight + margin; }; /** * Close the palette */ Palette.prototype.close = function () { this._toggleState({ open: false, twoColumn: false }); }; /** * Open the palette */ Palette.prototype.open = function () { this._toggleState({ open: true }); }; Palette.prototype.toggle = function (open) { if (this.isOpen()) { this.close(); } else { this.open(); } }; Palette.prototype.isActiveTool = function (tool) { return tool && this._activeTool === tool; }; Palette.prototype.updateToolHighlight = function (name) { var entriesContainer, toolsContainer; if (!this._toolsContainer) { entriesContainer = (0, _minDom.query)('.djs-palette-entries', this._container); this._toolsContainer = (0, _minDom.query)('[data-group=tools]', entriesContainer); } toolsContainer = this._toolsContainer; (0, _minDash.forEach)(toolsContainer.children, function (tool) { var actionName = tool.getAttribute('data-action'); if (!actionName) { return; } var toolClasses = (0, _minDom.classes)(tool); actionName = actionName.replace('-tool', ''); if (toolClasses.contains('entry') && actionName === name) { toolClasses.add('highlighted-entry'); } else { toolClasses.remove('highlighted-entry'); } }); }; /** * Return true if the palette is opened. * * @example * * palette.open(); * * if (palette.isOpen()) { * // yes, we are open * } * * @return {boolean} true if palette is opened */ Palette.prototype.isOpen = function () { return (0, _minDom.classes)(this._container).has(PALETTE_OPEN_CLS); }; /** * Get container the palette lives in. * * @return {Element} */ Palette.prototype._getParentContainer = function () { return this._canvas.getContainer(); }; /* markup definition */ Palette.HTML_MARKUP = '
' + '
' + '
' + '
'; // helpers ////////////////////// function addClasses(element, classNames) { var classes = (0, _minDom.classes)(element); var actualClassNames = (0, _minDash.isArray)(classNames) ? classNames : classNames.split(/\s+/g); actualClassNames.forEach(function (cls) { classes.add(cls); }); } },{"min-dash":505,"min-dom":506}],341:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _Palette = require('./Palette'); var _Palette2 = _interopRequireDefault(_Palette); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['palette'], palette: ['type', _Palette2.default] }; },{"./Palette":340}],342:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = PopupMenu; var _minDash = require('min-dash'); var _minDom = require('min-dom'); var DATA_REF = 'data-id'; /** * A popup menu that can be used to display a list of actions anywhere in the canvas. * * @param {Object} config * @param {Boolean|Object} [config.scale={ min: 1.0, max: 1.5 }] * @param {Number} [config.scale.min] * @param {Number} [config.scale.max] * @param {EventBus} eventBus * @param {Canvas} canvas * * @class * @constructor */ function PopupMenu(config, eventBus, canvas) { var scale = (0, _minDash.isDefined)(config && config.scale) ? config.scale : { min: 1, max: 1.5 }; this._config = { scale: scale }; this._eventBus = eventBus; this._canvas = canvas; this._providers = {}; this._current = {}; } PopupMenu.$inject = ['config.popupMenu', 'eventBus', 'canvas']; /** * Registers a popup menu provider * * @param {String} id * @param {Object} provider * * @example * * popupMenu.registerProvider('myMenuID', { * getEntries: function(element) { * return [ * { * id: 'entry-1', * label: 'My Entry', * action: 'alert("I have been clicked!")' * } * ]; * } * }); */ PopupMenu.prototype.registerProvider = function (id, provider) { this._providers[id] = provider; }; /** * Determine if the popup menu has entries. * * @return {Boolean} true if empty */ PopupMenu.prototype.isEmpty = function (element, providerId) { if (!element) { throw new Error('element parameter is missing'); } if (!providerId) { throw new Error('providerId parameter is missing'); } var provider = this._providers[providerId]; var entries = provider.getEntries(element), headerEntries = provider.getHeaderEntries && provider.getHeaderEntries(element); var hasEntries = entries.length > 0, hasHeaderEntries = headerEntries && headerEntries.length > 0; return !hasEntries && !hasHeaderEntries; }; /** * Create entries and open popup menu at given position * * @param {Object} element * @param {String} id provider id * @param {Object} position * * @return {Object} popup menu instance */ PopupMenu.prototype.open = function (element, id, position) { var provider = this._providers[id]; if (!element) { throw new Error('Element is missing'); } if (!provider) { throw new Error('Provider is not registered: ' + id); } if (!position) { throw new Error('the position argument is missing'); } if (this.isOpen()) { this.close(); } this._emit('open'); var current = this._current = { provider: provider, className: id, element: element, position: position }; if (provider.getHeaderEntries) { current.headerEntries = provider.getHeaderEntries(element); } current.entries = provider.getEntries(element); current.container = this._createContainer(); var headerEntries = current.headerEntries || [], entries = current.entries || []; if (headerEntries.length) { current.container.appendChild(this._createEntries(current.headerEntries, 'djs-popup-header')); } if (entries.length) { current.container.appendChild(this._createEntries(current.entries, 'djs-popup-body')); } var canvas = this._canvas, parent = canvas.getContainer(); this._attachContainer(current.container, parent, position.cursor); }; /** * Removes the popup menu and unbinds the event handlers. */ PopupMenu.prototype.close = function () { if (!this.isOpen()) { return; } this._emit('close'); this._unbindHandlers(); (0, _minDom.remove)(this._current.container); this._current.container = null; }; /** * Determine if an open popup menu exist. * * @return {Boolean} true if open */ PopupMenu.prototype.isOpen = function () { return !!this._current.container; }; /** * Trigger an action associated with an entry. * * @param {Object} event * * @return the result of the action callback, if any */ PopupMenu.prototype.trigger = function (event) { // silence other actions event.preventDefault(); var element = event.delegateTarget || event.target, entryId = (0, _minDom.attr)(element, DATA_REF); var entry = this._getEntry(entryId); if (entry.action) { return entry.action.call(null, event, entry); } }; /** * Gets an entry instance (either entry or headerEntry) by id. * * @param {String} entryId * * @return {Object} entry instance */ PopupMenu.prototype._getEntry = function (entryId) { var search = (0, _minDash.matchPattern)({ id: entryId }); var entry = (0, _minDash.find)(this._current.entries, search) || (0, _minDash.find)(this._current.headerEntries, search); if (!entry) { throw new Error('entry not found'); } return entry; }; PopupMenu.prototype._emit = function (eventName) { this._eventBus.fire('popupMenu.' + eventName); }; /** * Creates the popup menu container. * * @return {Object} a DOM container */ PopupMenu.prototype._createContainer = function () { var container = (0, _minDom.domify)('
'), position = this._current.position, className = this._current.className; (0, _minDash.assign)(container.style, { position: 'absolute', left: position.x + 'px', top: position.y + 'px', visibility: 'hidden' }); (0, _minDom.classes)(container).add(className); return container; }; /** * Attaches the container to the DOM and binds the event handlers. * * @param {Object} container * @param {Object} parent */ PopupMenu.prototype._attachContainer = function (container, parent, cursor) { var self = this; // Event handler _minDom.delegate.bind(container, '.entry', 'click', function (event) { self.trigger(event); }); this._updateScale(container); // Attach to DOM parent.appendChild(container); if (cursor) { this._assureIsInbounds(container, cursor); } // Add Handler this._bindHandlers(); }; /** * Updates popup style.transform with respect to the config and zoom level. * * @method _updateScale * * @param {Object} container */ PopupMenu.prototype._updateScale = function (container) { var zoom = this._canvas.zoom(); var scaleConfig = this._config.scale, minScale, maxScale, scale = zoom; if (scaleConfig !== true) { if (scaleConfig === false) { minScale = 1; maxScale = 1; } else { minScale = scaleConfig.min; maxScale = scaleConfig.max; } if ((0, _minDash.isDefined)(minScale) && zoom < minScale) { scale = minScale; } if ((0, _minDash.isDefined)(maxScale) && zoom > maxScale) { scale = maxScale; } } setTransform(container, 'scale(' + scale + ')'); }; /** * Make sure that the menu is always fully shown * * @method function * * @param {Object} container * @param {Position} cursor {x, y} */ PopupMenu.prototype._assureIsInbounds = function (container, cursor) { var canvas = this._canvas, clientRect = canvas._container.getBoundingClientRect(); var containerX = container.offsetLeft, containerY = container.offsetTop, containerWidth = container.scrollWidth, containerHeight = container.scrollHeight, overAxis = {}, left, top; var cursorPosition = { x: cursor.x - clientRect.left, y: cursor.y - clientRect.top }; if (containerX + containerWidth > clientRect.width) { overAxis.x = true; } if (containerY + containerHeight > clientRect.height) { overAxis.y = true; } if (overAxis.x && overAxis.y) { left = cursorPosition.x - containerWidth + 'px'; top = cursorPosition.y - containerHeight + 'px'; } else if (overAxis.x) { left = cursorPosition.x - containerWidth + 'px'; top = cursorPosition.y + 'px'; } else if (overAxis.y && cursorPosition.y < containerHeight) { left = cursorPosition.x + 'px'; top = 10 + 'px'; } else if (overAxis.y) { left = cursorPosition.x + 'px'; top = cursorPosition.y - containerHeight + 'px'; } (0, _minDash.assign)(container.style, { left: left, top: top }, { visibility: 'visible', 'z-index': 1000 }); }; /** * Creates a list of entries and returns them as a DOM container. * * @param {Array} entries an array of entry objects * @param {String} className the class name of the entry container * * @return {Object} a DOM container */ PopupMenu.prototype._createEntries = function (entries, className) { var entriesContainer = (0, _minDom.domify)('
'), self = this; (0, _minDom.classes)(entriesContainer).add(className); (0, _minDash.forEach)(entries, function (entry) { var entryContainer = self._createEntry(entry, entriesContainer); entriesContainer.appendChild(entryContainer); }); return entriesContainer; }; /** * Creates a single entry and returns it as a DOM container. * * @param {Object} entry * * @return {Object} a DOM container */ PopupMenu.prototype._createEntry = function (entry) { if (!entry.id) { throw new Error('every entry must have the id property set'); } var entryContainer = (0, _minDom.domify)('
'), entryClasses = (0, _minDom.classes)(entryContainer); entryClasses.add('entry'); if (entry.className) { entry.className.split(' ').forEach(function (className) { entryClasses.add(className); }); } (0, _minDom.attr)(entryContainer, DATA_REF, entry.id); if (entry.label) { var label = (0, _minDom.domify)(''); label.textContent = entry.label; entryContainer.appendChild(label); } if (entry.imageUrl) { entryContainer.appendChild((0, _minDom.domify)('')); } if (entry.active === true) { entryClasses.add('active'); } if (entry.disabled === true) { entryClasses.add('disabled'); } if (entry.title) { entryContainer.title = entry.title; } return entryContainer; }; /** * Binds the `close` method to 'contextPad.close' & 'canvas.viewbox.changed'. */ PopupMenu.prototype._bindHandlers = function () { var eventBus = this._eventBus, self = this; function close() { self.close(); } eventBus.once('contextPad.close', close); eventBus.once('canvas.viewbox.changing', close); eventBus.once('commandStack.changed', close); }; /** * Unbinds the `close` method to 'contextPad.close' & 'canvas.viewbox.changing'. */ PopupMenu.prototype._unbindHandlers = function () { var eventBus = this._eventBus, self = this; function close() { self.close(); } eventBus.off('contextPad.close', close); eventBus.off('canvas.viewbox.changed', close); eventBus.off('commandStack.changed', close); }; // helpers ///////////////////////////// function setTransform(element, transform) { element.style['transform-origin'] = 'top left'; ['', '-ms-', '-webkit-'].forEach(function (prefix) { element.style[prefix + 'transform'] = transform; }); } },{"min-dash":505,"min-dom":506}],343:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _PopupMenu = require('./PopupMenu'); var _PopupMenu2 = _interopRequireDefault(_PopupMenu); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['popupMenu'], popupMenu: ['type', _PopupMenu2.default] }; },{"./PopupMenu":342}],344:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = PreviewSupport; var _minDash = require('min-dash'); var _tinySvg = require('tiny-svg'); /** * Adds support for previews of moving/resizing elements. */ function PreviewSupport(elementRegistry, canvas, styles) { this._elementRegistry = elementRegistry; this._canvas = canvas; this._styles = styles; } PreviewSupport.$inject = ['elementRegistry', 'canvas', 'styles']; /** * Returns graphics of an element. * * @param {djs.model.Base} element * * @return {SVGElement} */ PreviewSupport.prototype.getGfx = function (element) { return this._elementRegistry.getGraphics(element); }; /** * Adds a move preview of a given shape to a given svg group. * * @param {djs.model.Base} element * @param {SVGElement} group * * @return {SVGElement} dragger */ PreviewSupport.prototype.addDragger = function (shape, group) { var gfx = this.getGfx(shape); // clone is not included in tsvg for some reason var dragger = (0, _tinySvg.clone)(gfx); var bbox = gfx.getBoundingClientRect(); // remove markers from connections if (isConnection(shape)) { removeMarkers(dragger); } (0, _tinySvg.attr)(dragger, this._styles.cls('djs-dragger', [], { x: bbox.top, y: bbox.left })); (0, _tinySvg.append)(group, dragger); return dragger; }; /** * Adds a resize preview of a given shape to a given svg group. * * @param {djs.model.Base} element * @param {SVGElement} group * * @return {SVGElement} frame */ PreviewSupport.prototype.addFrame = function (shape, group) { var frame = (0, _tinySvg.create)('rect', { class: 'djs-resize-overlay', width: shape.width, height: shape.height, x: shape.x, y: shape.y }); (0, _tinySvg.append)(group, frame); return frame; }; // helpers ////////////////////// /** * Removes all svg marker references from an SVG. * * @param {SVGElement} gfx */ function removeMarkers(gfx) { if (gfx.children) { (0, _minDash.forEach)(gfx.children, function (child) { // recursion removeMarkers(child); }); } gfx.style.markerStart = ''; gfx.style.markerEnd = ''; } /** * Checks if an element is a connection. */ function isConnection(element) { return element.waypoints; } },{"min-dash":505,"tiny-svg":535}],345:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _PreviewSupport = require('./PreviewSupport'); var _PreviewSupport2 = _interopRequireDefault(_PreviewSupport); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['previewSupport'], previewSupport: ['type', _PreviewSupport2.default] }; },{"./PreviewSupport":344}],346:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Replace; var round = Math.round; /** * Service that allow replacing of elements. */ function Replace(modeling) { this._modeling = modeling; } Replace.$inject = ['modeling']; /** * @param {Element} oldElement - Element to be replaced * @param {Object} newElementData - Containing information about the new Element, for example height, width, type. * @param {Object} options - Custom options that will be attached to the context. It can be used to inject data * that is needed in the command chain. For example it could be used in * eventbus.on('commandStack.shape.replace.postExecute') to change shape attributes after * shape creation. */ Replace.prototype.replaceElement = function (oldElement, newElementData, options) { var modeling = this._modeling; var newElement = null; if (oldElement.waypoints) { // TODO // modeling.replaceConnection } else { // set center of element for modeling API // if no new width / height is given use old elements size newElementData.x = round(oldElement.x + (newElementData.width || oldElement.width) / 2); newElementData.y = round(oldElement.y + (newElementData.height || oldElement.height) / 2); newElement = modeling.replaceShape(oldElement, newElementData, options); } return newElement; }; },{}],347:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _Replace = require('./Replace'); var _Replace2 = _interopRequireDefault(_Replace); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['replace'], replace: ['type', _Replace2.default] }; },{"./Replace":346}],348:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Resize; var _minDash = require('min-dash'); var _ResizeUtil = require('./ResizeUtil'); var _LayoutUtil = require('../../layout/LayoutUtil'); var DEFAULT_MIN_WIDTH = 10; /** * A component that provides resizing of shapes on the canvas. * * The following components are part of shape resize: * * * adding resize handles, * * creating a visual during resize * * checking resize rules * * committing a change once finished * * * ## Customizing * * It's possible to customize the resizing behaviour by intercepting 'resize.start' * and providing the following parameters through the 'context': * * * minDimensions ({ width, height }): minimum shape dimensions * * * childrenBoxPadding ({ left, top, bottom, right } || number): * gap between the minimum bounding box and the container * * f.ex: * * ```javascript * eventBus.on('resize.start', 1500, function(event) { * var context = event.context, * * context.minDimensions = { width: 140, height: 120 }; * * // Passing general padding * context.childrenBoxPadding = 30; * * // Passing padding to a specific side * context.childrenBoxPadding.left = 20; * }); * ``` */ function Resize(eventBus, rules, modeling, dragging) { this._dragging = dragging; this._rules = rules; var self = this; /** * Handle resize move by specified delta. * * @param {Object} context * @param {Point delta */ function handleMove(context, delta) { var shape = context.shape, direction = context.direction, resizeConstraints = context.resizeConstraints, newBounds; context.delta = delta; newBounds = (0, _ResizeUtil.resizeBounds)(shape, direction, delta); // ensure constraints during resize context.newBounds = (0, _ResizeUtil.ensureConstraints)(newBounds, resizeConstraints); // update + cache executable state context.canExecute = self.canResize(context); } /** * Handle resize start. * * @param {Object} context */ function handleStart(context) { var resizeConstraints = context.resizeConstraints, // evaluate minBounds for backwards compatibility minBounds = context.minBounds; if (resizeConstraints !== undefined) { return; } if (minBounds === undefined) { minBounds = self.computeMinResizeBox(context); } context.resizeConstraints = { min: (0, _LayoutUtil.asTRBL)(minBounds) }; } /** * Handle resize end. * * @param {Object} context */ function handleEnd(context) { var shape = context.shape, canExecute = context.canExecute, newBounds = context.newBounds; if (canExecute) { // ensure we have actual pixel values for new bounds // (important when zoom level was > 1 during move) newBounds = (0, _LayoutUtil.roundBounds)(newBounds); // perform the actual resize modeling.resizeShape(shape, newBounds); } } eventBus.on('resize.start', function (event) { handleStart(event.context); }); eventBus.on('resize.move', function (event) { var delta = { x: event.dx, y: event.dy }; handleMove(event.context, delta); }); eventBus.on('resize.end', function (event) { handleEnd(event.context); }); } Resize.prototype.canResize = function (context) { var rules = this._rules; var ctx = (0, _minDash.pick)(context, ['newBounds', 'shape', 'delta', 'direction']); return rules.allowed('shape.resize', ctx); }; /** * Activate a resize operation. * * You may specify additional contextual information and must specify a * resize direction during activation of the resize event. * * @param {MouseEvent} event * @param {djs.model.Shape} shape * @param {Object|String} contextOrDirection */ Resize.prototype.activate = function (event, shape, contextOrDirection) { var dragging = this._dragging, context, direction; if (typeof contextOrDirection === 'string') { contextOrDirection = { direction: contextOrDirection }; } context = (0, _minDash.assign)({ shape: shape }, contextOrDirection); direction = context.direction; if (!direction) { throw new Error('must provide a direction (nw|se|ne|sw)'); } dragging.init(event, 'resize', { autoActivate: true, cursor: 'resize-' + (/nw|se/.test(direction) ? 'nwse' : 'nesw'), data: { shape: shape, context: context } }); }; Resize.prototype.computeMinResizeBox = function (context) { var shape = context.shape, direction = context.direction, minDimensions, childrenBounds; minDimensions = context.minDimensions || { width: DEFAULT_MIN_WIDTH, height: DEFAULT_MIN_WIDTH }; // get children bounds childrenBounds = (0, _ResizeUtil.computeChildrenBBox)(shape, context.childrenBoxPadding); // get correct minimum bounds from given resize direction // basically ensures that the minBounds is max(childrenBounds, minDimensions) return (0, _ResizeUtil.getMinResizeBounds)(direction, shape, minDimensions, childrenBounds); }; Resize.$inject = ['eventBus', 'rules', 'modeling', 'dragging']; },{"../../layout/LayoutUtil":380,"./ResizeUtil":351,"min-dash":505}],349:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ResizeHandles; var _minDash = require('min-dash'); var _tinySvg = require('tiny-svg'); var _minDom = require('min-dom'); var _Mouse = require('../../util/Mouse'); var _LayoutUtil = require('../../layout/LayoutUtil'); var _SvgTransformUtil = require('../../util/SvgTransformUtil'); var HANDLE_OFFSET = -2, HANDLE_SIZE = 5, HANDLE_HIT_SIZE = 20; var CLS_RESIZER = 'djs-resizer'; /** * This component is responsible for adding resize handles. * * @param {EventBus} eventBus * @param {Canvas} canvas * @param {Selection} selection * @param {Resize} resize */ function ResizeHandles(eventBus, canvas, selection, resize) { this._resize = resize; this._canvas = canvas; var self = this; eventBus.on('selection.changed', function (e) { var newSelection = e.newSelection; // remove old selection markers self.removeResizers(); // add new selection markers ONLY if single selection if (newSelection.length === 1) { (0, _minDash.forEach)(newSelection, (0, _minDash.bind)(self.addResizer, self)); } }); eventBus.on('shape.changed', function (e) { var shape = e.element; if (selection.isSelected(shape)) { self.removeResizers(); self.addResizer(shape); } }); } ResizeHandles.prototype.makeDraggable = function (element, gfx, direction) { var resize = this._resize; function startResize(event) { // only trigger on left mouse button if ((0, _Mouse.isPrimaryButton)(event)) { resize.activate(event, element, direction); } } _minDom.event.bind(gfx, 'mousedown', startResize); _minDom.event.bind(gfx, 'touchstart', startResize); }; ResizeHandles.prototype._createResizer = function (element, x, y, rotation, direction) { var resizersParent = this._getResizersParent(); var group = (0, _tinySvg.create)('g'); (0, _tinySvg.classes)(group).add(CLS_RESIZER); (0, _tinySvg.classes)(group).add(CLS_RESIZER + '-' + element.id); (0, _tinySvg.classes)(group).add(CLS_RESIZER + '-' + direction); (0, _tinySvg.append)(resizersParent, group); var origin = -HANDLE_SIZE + HANDLE_OFFSET; // Create four drag indicators on the outline var visual = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(visual, { x: origin, y: origin, width: HANDLE_SIZE, height: HANDLE_SIZE }); (0, _tinySvg.classes)(visual).add(CLS_RESIZER + '-visual'); (0, _tinySvg.append)(group, visual); var hit = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(hit, { x: origin, y: origin, width: HANDLE_HIT_SIZE, height: HANDLE_HIT_SIZE }); (0, _tinySvg.classes)(hit).add(CLS_RESIZER + '-hit'); (0, _tinySvg.append)(group, hit); (0, _SvgTransformUtil.transform)(group, x, y, rotation); return group; }; ResizeHandles.prototype.createResizer = function (element, direction) { var resizer; var trbl = (0, _LayoutUtil.asTRBL)(element); if (direction === 'nw') { resizer = this._createResizer(element, trbl.left, trbl.top, 0, direction); } else if (direction === 'ne') { resizer = this._createResizer(element, trbl.right, trbl.top, 90, direction); } else if (direction === 'se') { resizer = this._createResizer(element, trbl.right, trbl.bottom, 180, direction); } else { resizer = this._createResizer(element, trbl.left, trbl.bottom, 270, direction); } this.makeDraggable(element, resizer, direction); }; // resize handles implementation /////////////////////////////// /** * Add resizers for a given element. * * @param {djs.model.Shape} shape */ ResizeHandles.prototype.addResizer = function (shape) { var resize = this._resize; if (!resize.canResize({ shape: shape })) { return; } this.createResizer(shape, 'nw'); this.createResizer(shape, 'ne'); this.createResizer(shape, 'se'); this.createResizer(shape, 'sw'); }; /** * Remove all resizers */ ResizeHandles.prototype.removeResizers = function () { var resizersParent = this._getResizersParent(); (0, _tinySvg.clear)(resizersParent); }; ResizeHandles.prototype._getResizersParent = function () { return this._canvas.getLayer('resizers'); }; ResizeHandles.$inject = ['eventBus', 'canvas', 'selection', 'resize']; },{"../../layout/LayoutUtil":380,"../../util/Mouse":403,"../../util/SvgTransformUtil":408,"min-dash":505,"min-dom":506,"tiny-svg":535}],350:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ResizePreview; var _tinySvg = require('tiny-svg'); var MARKER_RESIZING = 'djs-resizing', MARKER_RESIZE_NOT_OK = 'resize-not-ok'; var LOW_PRIORITY = 500; /** * Provides previews for resizing shapes when resizing. * * @param {EventBus} eventBus * @param {Canvas} canvas * @param {PreviewSupport} previewSupport */ function ResizePreview(eventBus, canvas, previewSupport) { /** * Update resizer frame. * * @param {Object} context */ function updateFrame(context) { var shape = context.shape, bounds = context.newBounds, frame = context.frame; if (!frame) { frame = context.frame = previewSupport.addFrame(shape, canvas.getDefaultLayer()); canvas.addMarker(shape, MARKER_RESIZING); } if (bounds.width > 5) { (0, _tinySvg.attr)(frame, { x: bounds.x, width: bounds.width }); } if (bounds.height > 5) { (0, _tinySvg.attr)(frame, { y: bounds.y, height: bounds.height }); } if (context.canExecute) { (0, _tinySvg.classes)(frame).remove(MARKER_RESIZE_NOT_OK); } else { (0, _tinySvg.classes)(frame).add(MARKER_RESIZE_NOT_OK); } } /** * Remove resizer frame. * * @param {Object} context */ function removeFrame(context) { var shape = context.shape, frame = context.frame; if (frame) { (0, _tinySvg.remove)(context.frame); } canvas.removeMarker(shape, MARKER_RESIZING); } // add and update previews eventBus.on('resize.move', LOW_PRIORITY, function (event) { updateFrame(event.context); }); // remove previews eventBus.on('resize.cleanup', function (event) { removeFrame(event.context); }); } ResizePreview.$inject = ['eventBus', 'canvas', 'previewSupport']; },{"tiny-svg":535}],351:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; exports.substractTRBL = substractTRBL; exports.resizeBounds = resizeBounds; exports.resizeTRBL = resizeTRBL; exports.reattachPoint = reattachPoint; exports.ensureConstraints = ensureConstraints; exports.getMinResizeBounds = getMinResizeBounds; exports.addPadding = addPadding; exports.computeChildrenBBox = computeChildrenBBox; var _minDash = require('min-dash'); var _Elements = require('../../util/Elements'); var _LayoutUtil = require('../../layout/LayoutUtil'); var max = Math.max, min = Math.min; var DEFAULT_CHILD_BOX_PADDING = 20; /** * Substract a TRBL from another * * @param {TRBL} trblA * @param {TRBL} trblB * * @return {TRBL} */ function substractTRBL(trblA, trblB) { return { top: trblA.top - trblB.top, right: trblA.right - trblB.right, bottom: trblA.bottom - trblB.bottom, left: trblA.left - trblB.left }; } /** * Resize the given bounds by the specified delta from a given anchor point. * * @param {Bounds} bounds the bounding box that should be resized * @param {String} direction in which the element is resized (nw, ne, se, sw) * @param {Point} delta of the resize operation * * @return {Bounds} resized bounding box */ function resizeBounds(bounds, direction, delta) { var dx = delta.x, dy = delta.y; switch (direction) { case 'nw': return { x: bounds.x + dx, y: bounds.y + dy, width: bounds.width - dx, height: bounds.height - dy }; case 'sw': return { x: bounds.x + dx, y: bounds.y, width: bounds.width - dx, height: bounds.height + dy }; case 'ne': return { x: bounds.x, y: bounds.y + dy, width: bounds.width + dx, height: bounds.height - dy }; case 'se': return { x: bounds.x, y: bounds.y, width: bounds.width + dx, height: bounds.height + dy }; default: throw new Error('unrecognized direction: ' + direction); } } /** * Resize the given bounds by applying the passed * { top, right, bottom, left } delta. * * @param {Bounds} bounds * @param {TRBL} trblResize * * @return {Bounds} */ function resizeTRBL(bounds, resize) { return { x: bounds.x + (resize.left || 0), y: bounds.y + (resize.top || 0), width: bounds.width - (resize.left || 0) + (resize.right || 0), height: bounds.height - (resize.top || 0) + (resize.bottom || 0) }; } function reattachPoint(bounds, newBounds, point) { var sx = bounds.width / newBounds.width, sy = bounds.height / newBounds.height; return { x: Math.round(newBounds.x + newBounds.width / 2) - Math.floor((bounds.x + bounds.width / 2 - point.x) / sx), y: Math.round(newBounds.y + newBounds.height / 2) - Math.floor((bounds.y + bounds.height / 2 - point.y) / sy) }; } function applyConstraints(attr, trbl, resizeConstraints) { var value = trbl[attr], minValue = resizeConstraints.min && resizeConstraints.min[attr], maxValue = resizeConstraints.max && resizeConstraints.max[attr]; if ((0, _minDash.isNumber)(minValue)) { value = (/top|left/.test(attr) ? min : max)(value, minValue); } if ((0, _minDash.isNumber)(maxValue)) { value = (/top|left/.test(attr) ? max : min)(value, maxValue); } return value; } function ensureConstraints(currentBounds, resizeConstraints) { if (!resizeConstraints) { return currentBounds; } var currentTrbl = (0, _LayoutUtil.asTRBL)(currentBounds); return (0, _LayoutUtil.asBounds)({ top: applyConstraints('top', currentTrbl, resizeConstraints), right: applyConstraints('right', currentTrbl, resizeConstraints), bottom: applyConstraints('bottom', currentTrbl, resizeConstraints), left: applyConstraints('left', currentTrbl, resizeConstraints) }); } function getMinResizeBounds(direction, currentBounds, minDimensions, childrenBounds) { var currentBox = (0, _LayoutUtil.asTRBL)(currentBounds); var minBox = { top: /n/.test(direction) ? currentBox.bottom - minDimensions.height : currentBox.top, left: /w/.test(direction) ? currentBox.right - minDimensions.width : currentBox.left, bottom: /s/.test(direction) ? currentBox.top + minDimensions.height : currentBox.bottom, right: /e/.test(direction) ? currentBox.left + minDimensions.width : currentBox.right }; var childrenBox = childrenBounds ? (0, _LayoutUtil.asTRBL)(childrenBounds) : minBox; var combinedBox = { top: min(minBox.top, childrenBox.top), left: min(minBox.left, childrenBox.left), bottom: max(minBox.bottom, childrenBox.bottom), right: max(minBox.right, childrenBox.right) }; return (0, _LayoutUtil.asBounds)(combinedBox); } function asPadding(mayBePadding, defaultValue) { if (typeof mayBePadding !== 'undefined') { return mayBePadding; } else { return DEFAULT_CHILD_BOX_PADDING; } } function addPadding(bbox, padding) { var left, right, top, bottom; if ((typeof padding === 'undefined' ? 'undefined' : _typeof(padding)) === 'object') { left = asPadding(padding.left); right = asPadding(padding.right); top = asPadding(padding.top); bottom = asPadding(padding.bottom); } else { left = right = top = bottom = asPadding(padding); } return { x: bbox.x - left, y: bbox.y - top, width: bbox.width + left + right, height: bbox.height + top + bottom }; } /** * Is the given element part of the resize * targets min boundary box? * * This is the default implementation which excludes * connections and labels. * * @param {djs.model.Base} element */ function isBBoxChild(element) { // exclude connections if (element.waypoints) { return false; } // exclude labels if (element.type === 'label') { return false; } return true; } /** * Return children bounding computed from a shapes children * or a list of prefiltered children. * * @param {djs.model.Shape|Array} shapeOrChildren * @param {Number|Object} padding * * @return {Bounds} */ function computeChildrenBBox(shapeOrChildren, padding) { var elements; // compute based on shape if (shapeOrChildren.length === undefined) { // grab all the children that are part of the // parents children box elements = (0, _minDash.filter)(shapeOrChildren.children, isBBoxChild); } else { elements = shapeOrChildren; } if (elements.length) { return addPadding((0, _Elements.getBBox)(elements), padding); } } },{"../../layout/LayoutUtil":380,"../../util/Elements":396,"min-dash":505}],352:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _rules = require('../rules'); var _rules2 = _interopRequireDefault(_rules); var _dragging = require('../dragging'); var _dragging2 = _interopRequireDefault(_dragging); var _previewSupport = require('../preview-support'); var _previewSupport2 = _interopRequireDefault(_previewSupport); var _Resize = require('./Resize'); var _Resize2 = _interopRequireDefault(_Resize); var _ResizePreview = require('./ResizePreview'); var _ResizePreview2 = _interopRequireDefault(_ResizePreview); var _ResizeHandles = require('./ResizeHandles'); var _ResizeHandles2 = _interopRequireDefault(_ResizeHandles); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_rules2.default, _dragging2.default, _previewSupport2.default], __init__: ['resize', 'resizePreview', 'resizeHandles'], resize: ['type', _Resize2.default], resizePreview: ['type', _ResizePreview2.default], resizeHandles: ['type', _ResizeHandles2.default] }; },{"../dragging":286,"../preview-support":345,"../rules":355,"./Resize":348,"./ResizeHandles":349,"./ResizePreview":350}],353:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = RuleProvider; var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _CommandInterceptor = require('../../command/CommandInterceptor'); var _CommandInterceptor2 = _interopRequireDefault(_CommandInterceptor); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A basic provider that may be extended to implement modeling rules. * * Extensions should implement the init method to actually add their custom * modeling checks. Checks may be added via the #addRule(action, fn) method. * * @param {EventBus} eventBus */ function RuleProvider(eventBus) { _CommandInterceptor2.default.call(this, eventBus); this.init(); } RuleProvider.$inject = ['eventBus']; (0, _inherits2.default)(RuleProvider, _CommandInterceptor2.default); /** * Adds a modeling rule for the given action, implemented through * a callback function. * * The function will receive the modeling specific action context * to perform its check. It must return `false` to disallow the * action from happening or `true` to allow the action. * * A rule provider may pass over the evaluation to lower priority * rules by returning return nothing (or undefined). * * @example * * ResizableRules.prototype.init = function() { * * \/** * * Return `true`, `false` or nothing to denote * * _allowed_, _not allowed_ and _continue evaluating_. * *\/ * this.addRule('shape.resize', function(context) { * * var shape = context.shape; * * if (!context.newBounds) { * // check general resizability * if (!shape.resizable) { * return false; * } * * // not returning anything (read: undefined) * // will continue the evaluation of other rules * // (with lower priority) * return; * } else { * // element must have minimum size of 10*10 points * return context.newBounds.width > 10 && context.newBounds.height > 10; * } * }); * }; * * @param {String|Array} actions the identifier for the modeling action to check * @param {Number} [priority] the priority at which this rule is being applied * @param {Function} fn the callback function that performs the actual check */ RuleProvider.prototype.addRule = function (actions, priority, fn) { var self = this; if (typeof actions === 'string') { actions = [actions]; } actions.forEach(function (action) { self.canExecute(action, priority, function (context, action, event) { return fn(context); }, true); }); }; /** * Implement this method to add new rules during provider initialization. */ RuleProvider.prototype.init = function () {}; },{"../../command/CommandInterceptor":243,"inherits":415}],354:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Rules; /** * A service that provides rules for certain diagram actions. * * The default implementation will hook into the {@link CommandStack} * to perform the actual rule evaluation. Make sure to provide the * `commandStack` service with this module if you plan to use it. * * Together with this implementation you may use the {@link RuleProvider} * to implement your own rule checkers. * * This module is ment to be easily replaced, thus the tiny foot print. * * @param {Injector} injector */ function Rules(injector) { this._commandStack = injector.get('commandStack', false); } Rules.$inject = ['injector']; /** * Returns whether or not a given modeling action can be executed * in the specified context. * * This implementation will respond with allow unless anyone * objects. * * @param {String} action the action to be checked * @param {Object} [context] the context to check the action in * * @return {Boolean} returns true, false or null depending on whether the * operation is allowed, not allowed or should be ignored. */ Rules.prototype.allowed = function (action, context) { var allowed = true; var commandStack = this._commandStack; if (commandStack) { allowed = commandStack.canExecute(action, context); } // map undefined to true, i.e. no rules return allowed === undefined ? true : allowed; }; },{}],355:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _Rules = require('./Rules'); var _Rules2 = _interopRequireDefault(_Rules); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['rules'], rules: ['type', _Rules2.default] }; },{"./Rules":354}],356:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SearchPad; var _minDom = require('min-dom'); var _Elements = require('../../util/Elements'); /** * Provides searching infrastructure */ function SearchPad(canvas, eventBus, overlays, selection) { this._open = false; this._results = []; this._eventMaps = []; this._canvas = canvas; this._eventBus = eventBus; this._overlays = overlays; this._selection = selection; // setup elements this._container = (0, _minDom.domify)(SearchPad.BOX_HTML); this._searchInput = (0, _minDom.query)(SearchPad.INPUT_SELECTOR, this._container); this._resultsContainer = (0, _minDom.query)(SearchPad.RESULTS_CONTAINER_SELECTOR, this._container); // attach search pad this._canvas.getContainer().appendChild(this._container); // cleanup on destroy eventBus.on(['canvas.destroy', 'diagram.destroy'], this.close, this); } SearchPad.$inject = ['canvas', 'eventBus', 'overlays', 'selection']; /** * Binds and keeps track of all event listereners */ SearchPad.prototype._bindEvents = function () { var self = this; function listen(el, selector, type, fn) { self._eventMaps.push({ el: el, type: type, listener: _minDom.delegate.bind(el, selector, type, fn) }); } // close search on clicking anywhere outside listen(document, 'html', 'click', function (e) { self.close(); }, true); // stop event from propagating and closing search // focus on input listen(this._container, SearchPad.INPUT_SELECTOR, 'click', function (e) { e.stopPropagation(); e.delegateTarget.focus(); }); // preselect result on hover listen(this._container, SearchPad.RESULT_SELECTOR, 'mouseover', function (e) { e.stopPropagation(); self._scrollToNode(e.delegateTarget); self._preselect(e.delegateTarget); }); // selects desired result on mouse click listen(this._container, SearchPad.RESULT_SELECTOR, 'click', function (e) { e.stopPropagation(); self._select(e.delegateTarget); }); // prevent cursor in input from going left and right when using up/down to // navigate results listen(this._container, SearchPad.INPUT_SELECTOR, 'keydown', function (e) { // up if (e.keyCode === 38) { e.preventDefault(); } // down if (e.keyCode === 40) { e.preventDefault(); } }); // handle keyboard input listen(this._container, SearchPad.INPUT_SELECTOR, 'keyup', function (e) { // escape if (e.keyCode === 27) { return self.close(); } // enter if (e.keyCode === 13) { var selected = self._getCurrentResult(); return selected ? self._select(selected) : self.close(); } // up if (e.keyCode === 38) { return self._scrollToDirection(true); } // down if (e.keyCode === 40) { return self._scrollToDirection(); } // left && right // do not search while navigating text input if (e.keyCode === 37 || e.keyCode === 39) { return; } // anything else self._search(e.delegateTarget.value); }); }; /** * Unbinds all previously established listeners */ SearchPad.prototype._unbindEvents = function () { this._eventMaps.forEach(function (m) { _minDom.delegate.unbind(m.el, m.type, m.listener); }); }; /** * Performs a search for the given pattern. * * @param {String} pattern */ SearchPad.prototype._search = function (pattern) { var self = this; this._clearResults(); // do not search on empty query if (!pattern || pattern === '') { return; } var searchResults = this._searchProvider.find(pattern); if (!searchResults.length) { return; } // append new results searchResults.forEach(function (result) { var id = result.element.id; var node = self._createResultNode(result, id); self._results[id] = { element: result.element, node: node }; }); // preselect first result var node = (0, _minDom.query)(SearchPad.RESULT_SELECTOR, this._resultsContainer); this._scrollToNode(node); this._preselect(node); }; /** * Navigate to the previous/next result. Defaults to next result. * @param {Boolean} previous */ SearchPad.prototype._scrollToDirection = function (previous) { var selected = this._getCurrentResult(); if (!selected) { return; } var node = previous ? selected.previousElementSibling : selected.nextElementSibling; if (node) { this._scrollToNode(node); this._preselect(node); } }; /** * Scroll to the node if it is not visible. * * @param {Element} node */ SearchPad.prototype._scrollToNode = function (node) { if (!node || node === this._getCurrentResult()) { return; } var nodeOffset = node.offsetTop; var containerScroll = this._resultsContainer.scrollTop; var bottomScroll = nodeOffset - this._resultsContainer.clientHeight + node.clientHeight; if (nodeOffset < containerScroll) { this._resultsContainer.scrollTop = nodeOffset; } else if (containerScroll < bottomScroll) { this._resultsContainer.scrollTop = bottomScroll; } }; /** * Clears all results data. */ SearchPad.prototype._clearResults = function () { (0, _minDom.clear)(this._resultsContainer); this._results = []; this._resetOverlay(); this._eventBus.fire('searchPad.cleared'); }; /** * Get currently selected result. * * @return {Element} */ SearchPad.prototype._getCurrentResult = function () { return (0, _minDom.query)(SearchPad.RESULT_SELECTED_SELECTOR, this._resultsContainer); }; /** * Create result DOM element within results container * that corresponds to a search result. * * 'result' : one of the elements returned by SearchProvider * 'id' : id attribute value to assign to the new DOM node * return : created DOM element * * @param {SearchResult} result * @param {String} id * @return {Element} */ SearchPad.prototype._createResultNode = function (result, id) { var node = (0, _minDom.domify)(SearchPad.RESULT_HTML); // create only if available if (result.primaryTokens.length > 0) { createInnerTextNode(node, result.primaryTokens, SearchPad.RESULT_PRIMARY_HTML); } // secondary tokens (represent element ID) are allways available createInnerTextNode(node, result.secondaryTokens, SearchPad.RESULT_SECONDARY_HTML); (0, _minDom.attr)(node, SearchPad.RESULT_ID_ATTRIBUTE, id); this._resultsContainer.appendChild(node); return node; }; /** * Register search element provider. * * SearchProvider.find - provides search function over own elements * (pattern) => [{ text: , element: }, ...] * * @param {SearchProvider} provider */ SearchPad.prototype.registerProvider = function (provider) { this._searchProvider = provider; }; /** * Open search pad. */ SearchPad.prototype.open = function () { if (!this._searchProvider) { throw new Error('no search provider registered'); } if (this.isOpen()) { return; } this._bindEvents(); this._open = true; (0, _minDom.classes)(this._container).add('open'); this._searchInput.focus(); this._eventBus.fire('searchPad.opened'); }; /** * Close search pad. */ SearchPad.prototype.close = function () { if (!this.isOpen()) { return; } this._unbindEvents(); this._open = false; (0, _minDom.classes)(this._container).remove('open'); this._clearResults(); this._searchInput.value = ''; this._searchInput.blur(); this._resetOverlay(); this._eventBus.fire('searchPad.closed'); }; /** * Toggles search pad on/off. */ SearchPad.prototype.toggle = function () { this.isOpen() ? this.close() : this.open(); }; /** * Report state of search pad. */ SearchPad.prototype.isOpen = function () { return this._open; }; /** * Preselect result entry. * * @param {Element} element */ SearchPad.prototype._preselect = function (node) { var selectedNode = this._getCurrentResult(); // already selected if (node === selectedNode) { return; } // removing preselection from current node if (selectedNode) { (0, _minDom.classes)(selectedNode).remove(SearchPad.RESULT_SELECTED_CLASS); } var id = (0, _minDom.attr)(node, SearchPad.RESULT_ID_ATTRIBUTE); var element = this._results[id].element; (0, _minDom.classes)(node).add(SearchPad.RESULT_SELECTED_CLASS); this._resetOverlay(element); this._centerViewbox(element); this._selection.select(element); this._eventBus.fire('searchPad.preselected', element); }; /** * Select result node. * * @param {Element} element */ SearchPad.prototype._select = function (node) { var id = (0, _minDom.attr)(node, SearchPad.RESULT_ID_ATTRIBUTE); var element = this._results[id].element; this.close(); this._resetOverlay(); this._centerViewbox(element); this._selection.select(element); this._eventBus.fire('searchPad.selected', element); }; /** * Center viewbox on the element middle point. * * @param {Element} element */ SearchPad.prototype._centerViewbox = function (element) { var viewbox = this._canvas.viewbox(); var box = (0, _Elements.getBBox)(element); var newViewbox = { x: box.x + box.width / 2 - viewbox.outer.width / 2, y: box.y + box.height / 2 - viewbox.outer.height / 2, width: viewbox.outer.width, height: viewbox.outer.height }; this._canvas.viewbox(newViewbox); this._canvas.zoom(viewbox.scale); }; /** * Reset overlay removes and, optionally, set * overlay to a new element. * * @param {Element} element */ SearchPad.prototype._resetOverlay = function (element) { if (this._overlayId) { this._overlays.remove(this._overlayId); } if (element) { var box = (0, _Elements.getBBox)(element); var overlay = constructOverlay(box); this._overlayId = this._overlays.add(element, overlay); } }; /** * Construct overlay object for the given bounding box. * * @param {BoundingBox} box * @return {Object} */ function constructOverlay(box) { var offset = 6; var w = box.width + offset * 2; var h = box.height + offset * 2; var styles = ['width: ' + w + 'px', 'height: ' + h + 'px'].join('; '); return { position: { bottom: h - offset, right: w - offset }, show: true, html: '
' }; } /** * Creates and appends child node from result tokens and HTML template. * * @param {Element} node * @param {Array} tokens * @param {String} template */ function createInnerTextNode(parentNode, tokens, template) { var text = createHtmlText(tokens); var childNode = (0, _minDom.domify)(template); childNode.innerHTML = text; parentNode.appendChild(childNode); } /** * Create internal HTML markup from result tokens. * Caters for highlighting pattern matched tokens. * * @param {Array} tokens * @return {String} */ function createHtmlText(tokens) { var htmlText = ''; tokens.forEach(function (t) { if (t.matched) { htmlText += '' + t.matched + ''; } else { htmlText += t.normal; } }); return htmlText !== '' ? htmlText : null; } /** * CONSTANTS */ SearchPad.CONTAINER_SELECTOR = '.djs-search-container'; SearchPad.INPUT_SELECTOR = '.djs-search-input input'; SearchPad.RESULTS_CONTAINER_SELECTOR = '.djs-search-results'; SearchPad.RESULT_SELECTOR = '.djs-search-result'; SearchPad.RESULT_SELECTED_CLASS = 'djs-search-result-selected'; SearchPad.RESULT_SELECTED_SELECTOR = '.' + SearchPad.RESULT_SELECTED_CLASS; SearchPad.RESULT_ID_ATTRIBUTE = 'data-result-id'; SearchPad.RESULT_HIGHLIGHT_CLASS = 'djs-search-highlight'; SearchPad.OVERLAY_CLASS = 'djs-search-overlay'; SearchPad.BOX_HTML = '
' + '
' + '' + '
' + '
' + '
'; SearchPad.RESULT_HTML = '
'; SearchPad.RESULT_PRIMARY_HTML = '
'; SearchPad.RESULT_SECONDARY_HTML = '

'; },{"../../util/Elements":396,"min-dom":506}],357:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _overlays = require('../overlays'); var _overlays2 = _interopRequireDefault(_overlays); var _selection = require('../selection'); var _selection2 = _interopRequireDefault(_selection); var _SearchPad = require('./SearchPad'); var _SearchPad2 = _interopRequireDefault(_SearchPad); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_overlays2.default, _selection2.default], searchPad: ['type', _SearchPad2.default] }; },{"../overlays":339,"../selection":361,"./SearchPad":356}],358:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Selection; var _minDash = require('min-dash'); /** * A service that offers the current selection in a diagram. * Offers the api to control the selection, too. * * @class * * @param {EventBus} eventBus the event bus */ function Selection(eventBus) { this._eventBus = eventBus; this._selectedElements = []; var self = this; eventBus.on(['shape.remove', 'connection.remove'], function (e) { var element = e.element; self.deselect(element); }); eventBus.on(['diagram.clear'], function (e) { self.select(null); }); } Selection.$inject = ['eventBus']; Selection.prototype.deselect = function (element) { var selectedElements = this._selectedElements; var idx = selectedElements.indexOf(element); if (idx !== -1) { var oldSelection = selectedElements.slice(); selectedElements.splice(idx, 1); this._eventBus.fire('selection.changed', { oldSelection: oldSelection, newSelection: selectedElements }); } }; Selection.prototype.get = function () { return this._selectedElements; }; Selection.prototype.isSelected = function (element) { return this._selectedElements.indexOf(element) !== -1; }; /** * This method selects one or more elements on the diagram. * * By passing an additional add parameter you can decide whether or not the element(s) * should be added to the already existing selection or not. * * @method Selection#select * * @param {Object|Object[]} elements element or array of elements to be selected * @param {boolean} [add] whether the element(s) should be appended to the current selection, defaults to false */ Selection.prototype.select = function (elements, add) { var selectedElements = this._selectedElements, oldSelection = selectedElements.slice(); if (!(0, _minDash.isArray)(elements)) { elements = elements ? [elements] : []; } // selection may be cleared by passing an empty array or null // to the method if (add) { (0, _minDash.forEach)(elements, function (element) { if (selectedElements.indexOf(element) !== -1) { // already selected return; } else { selectedElements.push(element); } }); } else { this._selectedElements = selectedElements = elements.slice(); } this._eventBus.fire('selection.changed', { oldSelection: oldSelection, newSelection: selectedElements }); }; },{"min-dash":505}],359:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SelectionBehavior; var _Mouse = require('../../util/Mouse'); var _minDash = require('min-dash'); function SelectionBehavior(eventBus, selection, canvas, elementRegistry) { eventBus.on('create.end', 500, function (e) { // select the created shape after a // successful create operation if (e.context.canExecute) { selection.select(e.context.shape); } }); eventBus.on('connect.end', 500, function (e) { // select the connect end target // after a connect operation if (e.context.canExecute && e.context.target) { selection.select(e.context.target); } }); eventBus.on('shape.move.end', 500, function (e) { var previousSelection = e.previousSelection || []; var shape = elementRegistry.get(e.context.shape.id); // make sure at least the main moved element is being // selected after a move operation var inSelection = (0, _minDash.find)(previousSelection, function (selectedShape) { return shape.id === selectedShape.id; }); if (!inSelection) { selection.select(shape); } }); // Shift + click selection eventBus.on('element.click', function (event) { var element = event.element; // do not select the root element // or connections if (element === canvas.getRootElement()) { element = null; } var isSelected = selection.isSelected(element), isMultiSelect = selection.get().length > 1; // mouse-event: SELECTION_KEY var add = (0, _Mouse.hasPrimaryModifier)(event); // select OR deselect element in multi selection if (isSelected && isMultiSelect) { if (add) { return selection.deselect(element); } else { return selection.select(element); } } else if (!isSelected) { selection.select(element, add); } else { selection.deselect(element); } }); } SelectionBehavior.$inject = ['eventBus', 'selection', 'canvas', 'elementRegistry']; },{"../../util/Mouse":403,"min-dash":505}],360:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SelectionVisuals; var _minDash = require('min-dash'); var MARKER_HOVER = 'hover', MARKER_SELECTED = 'selected'; /** * A plugin that adds a visible selection UI to shapes and connections * by appending the hover and selected classes to them. * * @class * * Makes elements selectable, too. * * @param {EventBus} events * @param {SelectionService} selection * @param {Canvas} canvas */ function SelectionVisuals(events, canvas, selection, styles) { this._multiSelectionBox = null; function addMarker(e, cls) { canvas.addMarker(e, cls); } function removeMarker(e, cls) { canvas.removeMarker(e, cls); } events.on('element.hover', function (event) { addMarker(event.element, MARKER_HOVER); }); events.on('element.out', function (event) { removeMarker(event.element, MARKER_HOVER); }); events.on('selection.changed', function (event) { function deselect(s) { removeMarker(s, MARKER_SELECTED); } function select(s) { addMarker(s, MARKER_SELECTED); } var oldSelection = event.oldSelection, newSelection = event.newSelection; (0, _minDash.forEach)(oldSelection, function (e) { if (newSelection.indexOf(e) === -1) { deselect(e); } }); (0, _minDash.forEach)(newSelection, function (e) { if (oldSelection.indexOf(e) === -1) { select(e); } }); }); } SelectionVisuals.$inject = ['eventBus', 'canvas', 'selection', 'styles']; },{"min-dash":505}],361:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _interactionEvents = require('../interaction-events'); var _interactionEvents2 = _interopRequireDefault(_interactionEvents); var _outline = require('../outline'); var _outline2 = _interopRequireDefault(_outline); var _Selection = require('./Selection'); var _Selection2 = _interopRequireDefault(_Selection); var _SelectionVisuals = require('./SelectionVisuals'); var _SelectionVisuals2 = _interopRequireDefault(_SelectionVisuals); var _SelectionBehavior = require('./SelectionBehavior'); var _SelectionBehavior2 = _interopRequireDefault(_SelectionBehavior); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['selectionVisuals', 'selectionBehavior'], __depends__: [_interactionEvents2.default, _outline2.default], selection: ['type', _Selection2.default], selectionVisuals: ['type', _SelectionVisuals2.default], selectionBehavior: ['type', _SelectionBehavior2.default] }; },{"../interaction-events":294,"../outline":337,"./Selection":358,"./SelectionBehavior":359,"./SelectionVisuals":360}],362:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SnapContext; var _minDash = require('min-dash'); var _SnapUtil = require('./SnapUtil'); /** * A snap context, containing the (possibly incomplete) * mappings of drop targets (to identify the snapping) * to computed snap points. */ function SnapContext() { /** * Map mapping drop targets to * a list of possible snappings. * * @type {Object} */ this._targets = {}; /** * Map initial positioning of element * regarding various snap directions. * * @type {Object} */ this._snapOrigins = {}; /** * List of snap locations * * @type {Array} */ this._snapLocations = []; /** * Map> of default snapping locations * * @type {Object} */ this._defaultSnaps = {}; } SnapContext.prototype.getSnapOrigin = function (snapLocation) { return this._snapOrigins[snapLocation]; }; SnapContext.prototype.setSnapOrigin = function (snapLocation, initialValue) { this._snapOrigins[snapLocation] = initialValue; if (this._snapLocations.indexOf(snapLocation) === -1) { this._snapLocations.push(snapLocation); } }; SnapContext.prototype.addDefaultSnap = function (type, point) { var snapValues = this._defaultSnaps[type]; if (!snapValues) { snapValues = this._defaultSnaps[type] = []; } snapValues.push(point); }; /** * Return a number of initialized snaps, i.e. snap locations such as * top-left, mid, bottom-right and so forth. * * @return {Array} snapLocations */ SnapContext.prototype.getSnapLocations = function () { return this._snapLocations; }; /** * Set the snap locations for this context. * * The order of locations determines precedence. * * @param {Array} snapLocations */ SnapContext.prototype.setSnapLocations = function (snapLocations) { this._snapLocations = snapLocations; }; /** * Get snap points for a given target * * @param {Element|String} target */ SnapContext.prototype.pointsForTarget = function (target) { var targetId = target.id || target; var snapPoints = this._targets[targetId]; if (!snapPoints) { snapPoints = this._targets[targetId] = new SnapPoints(); snapPoints.initDefaults(this._defaultSnaps); } return snapPoints; }; /** * Creates the snap points and initializes them with the * given default values. * * @param {Object>} [defaultPoints] */ function SnapPoints(defaultSnaps) { /** * Map>> mapping snap locations, * i.e. top-left, bottom-right, center to actual snap values. * * @type {Object} */ this._snapValues = {}; } SnapPoints.prototype.add = function (snapLocation, point) { var snapValues = this._snapValues[snapLocation]; if (!snapValues) { snapValues = this._snapValues[snapLocation] = { x: [], y: [] }; } if (snapValues.x.indexOf(point.x) === -1) { snapValues.x.push(point.x); } if (snapValues.y.indexOf(point.y) === -1) { snapValues.y.push(point.y); } }; SnapPoints.prototype.snap = function (point, snapLocation, axis, tolerance) { var snappingValues = this._snapValues[snapLocation]; return snappingValues && (0, _SnapUtil.snapTo)(point[axis], snappingValues[axis], tolerance); }; /** * Initialize a number of default snapping points. * * @param {Object} defaultSnaps */ SnapPoints.prototype.initDefaults = function (defaultSnaps) { var self = this; (0, _minDash.forEach)(defaultSnaps || {}, function (snapPoints, snapLocation) { (0, _minDash.forEach)(snapPoints, function (point) { self.add(snapLocation, point); }); }); }; },{"./SnapUtil":363,"min-dash":505}],363:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.snapTo = snapTo; exports.topLeft = topLeft; exports.mid = mid; exports.bottomRight = bottomRight; exports.isSnapped = isSnapped; exports.setSnapped = setSnapped; var abs = Math.abs, round = Math.round; /** * Snap value to a collection of reference values. * * @param {Number} value * @param {Array} values * @param {Number} [tolerance=10] * * @return {Number} the value we snapped to or null, if none snapped */ function snapTo(value, values, tolerance) { tolerance = tolerance === undefined ? 10 : tolerance; var idx, snapValue; for (idx = 0; idx < values.length; idx++) { snapValue = values[idx]; if (abs(snapValue - value) <= tolerance) { return snapValue; } } } function topLeft(bounds) { return { x: bounds.x, y: bounds.y }; } function mid(bounds, defaultValue) { if (!bounds || isNaN(bounds.x) || isNaN(bounds.y)) { return defaultValue; } return { x: round(bounds.x + bounds.width / 2), y: round(bounds.y + bounds.height / 2) }; } function bottomRight(bounds) { return { x: bounds.x + bounds.width, y: bounds.y + bounds.height }; } /** * Retrieve the snap state of the given event. * * @param {Event} event * @param {String} axis * * @return {Boolean} the snapped state * */ function isSnapped(event, axis) { var snapped = event.snapped; if (!snapped) { return false; } if (typeof axis === 'string') { return snapped[axis]; } return snapped.x && snapped.y; } /** * Set the given event as snapped. * * This method may change the x and/or y position of the shape * from the given event! * * @param {Event} event * @param {String} axis * @param {Number|Boolean} value * * @return {Number} old value */ function setSnapped(event, axis, value) { if (typeof axis !== 'string') { throw new Error('axis must be in [x, y]'); } if (typeof value !== 'number' && value !== false) { throw new Error('value must be Number or false'); } var delta, previousValue = event[axis]; var snapped = event.snapped = event.snapped || {}; if (value === false) { snapped[axis] = false; } else { snapped[axis] = true; delta = value - previousValue; event[axis] += delta; event['d' + axis] += delta; } return previousValue; } },{}],364:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; exports.default = Snapping; var _minDash = require('min-dash'); var _SnapContext = require('./SnapContext'); var _SnapContext2 = _interopRequireDefault(_SnapContext); var _SnapUtil = require('./SnapUtil'); var _tinySvg = require('tiny-svg'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var HIGHER_PRIORITY = 1250; /** * A general purpose snapping component for diagram elements. * * @param {EventBus} eventBus * @param {Canvas} canvas */ function Snapping(eventBus, canvas) { this._canvas = canvas; var self = this; eventBus.on(['shape.move.start', 'create.start'], function (event) { self.initSnap(event); }); eventBus.on(['shape.move.move', 'shape.move.end', 'create.move', 'create.end'], HIGHER_PRIORITY, function (event) { if (event.originalEvent && event.originalEvent.ctrlKey) { return; } if ((0, _SnapUtil.isSnapped)(event)) { return; } self.snap(event); }); eventBus.on(['shape.move.cleanup', 'create.cleanup'], function (event) { self.hide(); }); // delay hide by 1000 seconds since last match this._asyncHide = (0, _minDash.debounce)((0, _minDash.bind)(this.hide, this), 1000); } Snapping.$inject = ['eventBus', 'canvas']; Snapping.prototype.initSnap = function (event) { var context = event.context, shape = context.shape, snapContext = context.snapContext; if (!snapContext) { snapContext = context.snapContext = new _SnapContext2.default(); } var snapMid = (0, _SnapUtil.mid)(shape, event); snapContext.setSnapOrigin('mid', { x: snapMid.x - event.x, y: snapMid.y - event.y }); return snapContext; }; Snapping.prototype.snap = function (event) { var context = event.context, snapContext = context.snapContext, shape = context.shape, target = context.target, snapLocations = snapContext.getSnapLocations(); if (!target) { return; } var snapPoints = snapContext.pointsForTarget(target); if (!snapPoints.initialized) { this.addTargetSnaps(snapPoints, shape, target); snapPoints.initialized = true; } var snapping = { x: (0, _SnapUtil.isSnapped)(event, 'x'), y: (0, _SnapUtil.isSnapped)(event, 'y') }; (0, _minDash.forEach)(snapLocations, function (location) { var snapOrigin = snapContext.getSnapOrigin(location); var snapCurrent = { x: event.x + snapOrigin.x, y: event.y + snapOrigin.y }; // snap on both axis, if not snapped already (0, _minDash.forEach)(['x', 'y'], function (axis) { var locationSnapping; if (!snapping[axis]) { locationSnapping = snapPoints.snap(snapCurrent, location, axis, 7); if (locationSnapping !== undefined) { snapping[axis] = { value: locationSnapping, originValue: locationSnapping - snapOrigin[axis] }; } } }); // no more need to snap, drop out of interation if (snapping.x && snapping.y) { return false; } }); // show snap visuals this.showSnapLine('vertical', snapping.x && snapping.x.value); this.showSnapLine('horizontal', snapping.y && snapping.y.value); // adjust event { x, y, dx, dy } and mark as snapping (0, _minDash.forEach)(['x', 'y'], function (axis) { var axisSnapping = snapping[axis]; if ((typeof axisSnapping === 'undefined' ? 'undefined' : _typeof(axisSnapping)) === 'object') { // set as snapped and adjust the x and/or y position of the event (0, _SnapUtil.setSnapped)(event, axis, axisSnapping.originValue); } }); }; Snapping.prototype._createLine = function (orientation) { var root = this._canvas.getLayer('snap'); // var line = root.path('M0,0 L0,0').addClass('djs-snap-line'); var line = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(line, { d: 'M0,0 L0,0' }); (0, _tinySvg.classes)(line).add('djs-snap-line'); (0, _tinySvg.append)(root, line); return { update: function update(position) { if (typeof position !== 'number') { (0, _tinySvg.attr)(line, { display: 'none' }); } else { if (orientation === 'horizontal') { (0, _tinySvg.attr)(line, { d: 'M-100000,' + position + ' L+100000,' + position, display: '' }); } else { (0, _tinySvg.attr)(line, { d: 'M ' + position + ',-100000 L ' + position + ', +100000', display: '' }); } } } }; }; Snapping.prototype._createSnapLines = function () { this._snapLines = { horizontal: this._createLine('horizontal'), vertical: this._createLine('vertical') }; }; Snapping.prototype.showSnapLine = function (orientation, position) { var line = this.getSnapLine(orientation); if (line) { line.update(position); } this._asyncHide(); }; Snapping.prototype.getSnapLine = function (orientation) { if (!this._snapLines) { this._createSnapLines(); } return this._snapLines[orientation]; }; Snapping.prototype.hide = function () { (0, _minDash.forEach)(this._snapLines, function (l) { l.update(); }); }; Snapping.prototype.addTargetSnaps = function (snapPoints, shape, target) { var siblings = this.getSiblings(shape, target); (0, _minDash.forEach)(siblings, function (s) { snapPoints.add('mid', (0, _SnapUtil.mid)(s)); }); }; Snapping.prototype.getSiblings = function (element, target) { // snap to all siblings that are not hidden, labels, attached to element or element itself return target && (0, _minDash.filter)(target.children, function (e) { return !e.hidden && !e.labelTarget && e.host !== element && e !== element; }); }; },{"./SnapContext":362,"./SnapUtil":363,"min-dash":505,"tiny-svg":535}],365:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SpaceTool; var _SpaceUtil = require('./SpaceUtil'); var _Cursor = require('../../util/Cursor'); var _Mouse = require('../../util/Mouse'); var _Elements = require('../../util/Elements'); var _minDash = require('min-dash'); var abs = Math.abs, round = Math.round; var HIGH_PRIORITY = 1500, SPACE_TOOL_CURSOR = 'crosshair'; var AXIS_TO_DIMENSION = { x: 'width', y: 'height' }, AXIS_INVERTED = { x: 'y', y: 'x' }; /** * A tool that allows users to create and remove space in a diagram. * * The tool needs to be activated manually via {@link SpaceTool#activate(MouseEvent)}. */ function SpaceTool(eventBus, dragging, canvas, modeling, rules, toolManager) { this._canvas = canvas; this._dragging = dragging; this._modeling = modeling; this._rules = rules; this._toolManager = toolManager; var self = this; toolManager.registerTool('space', { tool: 'spaceTool.selection', dragging: 'spaceTool' }); eventBus.on('spaceTool.selection.end', function (event) { var target = event.originalEvent.target; // only reactive on diagram click // on some occasions, event.hover is not set and we have to check if the target is an svg if (!event.hover && !(target instanceof SVGElement)) { return; } eventBus.once('spaceTool.selection.ended', function () { self.activateMakeSpace(event.originalEvent); }); }); eventBus.on('spaceTool.move', HIGH_PRIORITY, function (event) { var context = event.context; if (!context.initialized) { context.initialized = self.initializeMakeSpace(event, context); } }); eventBus.on('spaceTool.end', function (event) { var context = event.context, axis = context.axis, direction = context.direction, movingShapes = context.movingShapes, resizingShapes = context.resizingShapes; // skip if create space has not been initialized yet if (!context.initialized) { return; } var delta = { x: round(event.dx), y: round(event.dy) }; delta[AXIS_INVERTED[axis]] = 0; var insideBounds = true; // check if the space tool cursor is inside of bounds of // any of the shapes that would be resized. (0, _minDash.forEach)(resizingShapes, function (shape) { if (direction === 'w' && event.x > shape.x + shape.width || direction === 'e' && event.x < shape.x || direction === 'n' && event.y > shape.y + shape.height || direction === 's' && event.y < shape.y) { insideBounds = false; return; } }); if (insideBounds) { // make space only if the cursor is inside bounds self.makeSpace(movingShapes, resizingShapes, delta, direction); } eventBus.once('spaceTool.ended', function (event) { // reactivate space tool after usage self.activateSelection(event.originalEvent, true, true); }); }); } SpaceTool.$inject = ['eventBus', 'dragging', 'canvas', 'modeling', 'rules', 'toolManager']; /** * Activate space tool selection * * @param {MouseEvent} event * @param {Boolean} autoActivate */ SpaceTool.prototype.activateSelection = function (event, autoActivate, reactivate) { this._dragging.init(event, 'spaceTool.selection', { trapClick: false, cursor: SPACE_TOOL_CURSOR, autoActivate: autoActivate, data: { context: { reactivate: reactivate } } }); }; /** * Activate make space * * @param {MouseEvent} event */ SpaceTool.prototype.activateMakeSpace = function (event) { this._dragging.init(event, 'spaceTool', { autoActivate: true, cursor: SPACE_TOOL_CURSOR, data: { context: {} } }); }; /** * Actually make space on the diagram * * @param {Array} movingShapes * @param {Array} resizingShapes * @param {Point} delta * @param {String} direction */ SpaceTool.prototype.makeSpace = function (movingShapes, resizingShapes, delta, direction) { return this._modeling.createSpace(movingShapes, resizingShapes, delta, direction); }; /** * Initialize make space and return true if that was successful. * * @param {Event} event * @param {Object} context * * @return {Boolean} true, if successful */ SpaceTool.prototype.initializeMakeSpace = function (event, context) { var axis = abs(event.dx) > abs(event.dy) ? 'x' : 'y', offset = event['d' + axis], // start point of create space operation spacePos = event[axis] - offset; if (abs(offset) < 5) { return false; } // invert the offset in order to remove space when moving left if (offset < 0) { offset *= -1; } // inverts the offset to choose the shapes // on the opposite side of the resizer if // a key modifier is pressed if ((0, _Mouse.hasPrimaryModifier)(event)) { offset *= -1; } var rootShape = this._canvas.getRootElement(); var allShapes = (0, _Elements.selfAndAllChildren)(rootShape, true); var adjustments = this.calculateAdjustments(allShapes, axis, offset, spacePos); // store data in context (0, _minDash.assign)(context, adjustments, { axis: axis, direction: (0, _SpaceUtil.getDirection)(axis, offset) }); (0, _Cursor.set)('resize-' + (axis === 'x' ? 'ew' : 'ns')); return true; }; /** * Calculate adjustments needed when making space * * @param {Array} elements * @param {String} axis * @param {Number} offset * @param {Number} spacePos * * @return {Object} */ SpaceTool.prototype.calculateAdjustments = function (elements, axis, offset, spacePos) { var movingShapes = [], resizingShapes = []; var rules = this._rules; // collect all elements that need to be moved _AND_ // resized given on the initial create space position elements.forEach(function (shape) { var shapeStart = shape[axis], shapeEnd = shapeStart + shape[AXIS_TO_DIMENSION[axis]]; // checking if it's root if (!shape.parent) { return; } // checking if it's a shape if (shape.waypoints) { return; } // shape after spacePos if (offset > 0 && shapeStart > spacePos) { return movingShapes.push(shape); } // shape before spacePos if (offset < 0 && shapeEnd < spacePos) { return movingShapes.push(shape); } // shape on top of spacePos, resize only if allowed if (shapeStart < spacePos && shapeEnd > spacePos && rules.allowed('shape.resize', { shape: shape })) { return resizingShapes.push(shape); } }); return { movingShapes: movingShapes, resizingShapes: resizingShapes }; }; SpaceTool.prototype.toggle = function () { if (this.isActive()) { this._dragging.cancel(); } else { this.activateSelection(); } }; SpaceTool.prototype.isActive = function () { var context = this._dragging.context(); return context && /^spaceTool/.test(context.prefix); }; },{"../../util/Cursor":395,"../../util/Elements":396,"../../util/Mouse":403,"./SpaceUtil":367,"min-dash":505}],366:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SpaceToolPreview; var _minDash = require('min-dash'); var _tinySvg = require('tiny-svg'); var _SvgTransformUtil = require('../../util/SvgTransformUtil'); var MARKER_DRAGGING = 'djs-dragging', MARKER_RESIZING = 'djs-resizing'; var LOW_PRIORITY = 250; /** * Provides previews for selecting/moving/resizing shapes when creating/removing space. * * @param {EventBus} eventBus * @param {ElementRegistry} elementRegistry * @param {Canvas} canvas * @param {Styles} styles */ function SpaceToolPreview(eventBus, elementRegistry, canvas, styles, previewSupport) { function addPreviewGfx(collection, dragGroup) { (0, _minDash.forEach)(collection, function (element) { previewSupport.addDragger(element, dragGroup); canvas.addMarker(element, MARKER_DRAGGING); }); } // add crosshair eventBus.on('spaceTool.selection.start', function (event) { var space = canvas.getLayer('space'), context = event.context; var orientation = { x: 'M 0,-10000 L 0,10000', y: 'M -10000,0 L 10000,0' }; var crosshairGroup = (0, _tinySvg.create)('g'); (0, _tinySvg.attr)(crosshairGroup, styles.cls('djs-crosshair-group', ['no-events'])); (0, _tinySvg.append)(space, crosshairGroup); // horizontal path var pathX = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(pathX, 'd', orientation.x); (0, _tinySvg.classes)(pathX).add('djs-crosshair'); (0, _tinySvg.append)(crosshairGroup, pathX); // vertical path var pathY = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(pathY, 'd', orientation.y); (0, _tinySvg.classes)(pathY).add('djs-crosshair'); (0, _tinySvg.append)(crosshairGroup, pathY); context.crosshairGroup = crosshairGroup; }); // update crosshair eventBus.on('spaceTool.selection.move', function (event) { var crosshairGroup = event.context.crosshairGroup; (0, _SvgTransformUtil.translate)(crosshairGroup, event.x, event.y); }); // remove crosshair eventBus.on('spaceTool.selection.cleanup', function (event) { var context = event.context, crosshairGroup = context.crosshairGroup; if (crosshairGroup) { (0, _tinySvg.remove)(crosshairGroup); } }); // add and update move/resize previews eventBus.on('spaceTool.move', LOW_PRIORITY, function (event) { var context = event.context, line = context.line, axis = context.axis, movingShapes = context.movingShapes, resizingShapes = context.resizingShapes; if (!context.initialized) { return; } if (!context.dragGroup) { var spaceLayer = canvas.getLayer('space'); line = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(line, 'd', 'M0,0 L0,0'); (0, _tinySvg.classes)(line).add('djs-crosshair'); (0, _tinySvg.append)(spaceLayer, line); context.line = line; var dragGroup = (0, _tinySvg.create)('g'); (0, _tinySvg.attr)(dragGroup, styles.cls('djs-drag-group', ['no-events'])); (0, _tinySvg.append)(canvas.getDefaultLayer(), dragGroup); // shapes addPreviewGfx(movingShapes, dragGroup); // connections var movingConnections = context.movingConnections = elementRegistry.filter(function (element) { var sourceIsMoving = false; (0, _minDash.forEach)(movingShapes, function (shape) { (0, _minDash.forEach)(shape.outgoing, function (connection) { if (element === connection) { sourceIsMoving = true; } }); }); var targetIsMoving = false; (0, _minDash.forEach)(movingShapes, function (shape) { (0, _minDash.forEach)(shape.incoming, function (connection) { if (element === connection) { targetIsMoving = true; } }); }); var sourceIsResizing = false; (0, _minDash.forEach)(resizingShapes, function (shape) { (0, _minDash.forEach)(shape.outgoing, function (connection) { if (element === connection) { sourceIsResizing = true; } }); }); var targetIsResizing = false; (0, _minDash.forEach)(resizingShapes, function (shape) { (0, _minDash.forEach)(shape.incoming, function (connection) { if (element === connection) { targetIsResizing = true; } }); }); return isConnection(element) && (sourceIsMoving || sourceIsResizing) && (targetIsMoving || targetIsResizing); }); addPreviewGfx(movingConnections, dragGroup); context.dragGroup = dragGroup; } if (!context.frameGroup) { var frameGroup = (0, _tinySvg.create)('g'); (0, _tinySvg.attr)(frameGroup, styles.cls('djs-frame-group', ['no-events'])); (0, _tinySvg.append)(canvas.getDefaultLayer(), frameGroup); var frames = []; (0, _minDash.forEach)(resizingShapes, function (shape) { var frame = previewSupport.addFrame(shape, frameGroup); frames.push({ element: frame, initialWidth: frame.getBBox().width, initialHeight: frame.getBBox().height }); canvas.addMarker(shape, MARKER_RESIZING); }); context.frameGroup = frameGroup; context.frames = frames; } var orientation = { x: 'M' + event.x + ', -10000 L' + event.x + ', 10000', y: 'M -10000, ' + event.y + ' L 10000, ' + event.y }; (0, _tinySvg.attr)(line, { path: orientation[axis], display: '' }); var opposite = { x: 'y', y: 'x' }; var delta = { x: event.dx, y: event.dy }; delta[opposite[context.axis]] = 0; // update move previews (0, _SvgTransformUtil.translate)(context.dragGroup, delta.x, delta.y); // update resize previews (0, _minDash.forEach)(context.frames, function (frame) { if (frame.initialWidth + delta.x > 5) { (0, _tinySvg.attr)(frame.element, { width: frame.initialWidth + delta.x }); } if (frame.initialHeight + delta.y > 5) { (0, _tinySvg.attr)(frame.element, { height: frame.initialHeight + delta.y }); } }); }); // remove move/resize previews eventBus.on('spaceTool.cleanup', function (event) { var context = event.context, movingShapes = context.movingShapes, movingConnections = context.movingConnections, resizingShapes = context.resizingShapes, line = context.line, dragGroup = context.dragGroup, frameGroup = context.frameGroup; // moving shapes (0, _minDash.forEach)(movingShapes, function (shape) { canvas.removeMarker(shape, MARKER_DRAGGING); }); // moving connections (0, _minDash.forEach)(movingConnections, function (connection) { canvas.removeMarker(connection, MARKER_DRAGGING); }); if (dragGroup) { (0, _tinySvg.remove)(line); (0, _tinySvg.remove)(dragGroup); } (0, _minDash.forEach)(resizingShapes, function (shape) { canvas.removeMarker(shape, MARKER_RESIZING); }); if (frameGroup) { (0, _tinySvg.remove)(frameGroup); } }); } SpaceToolPreview.$inject = ['eventBus', 'elementRegistry', 'canvas', 'styles', 'previewSupport']; // helpers ////////////////////// /** * Checks if an element is a connection. */ function isConnection(element) { return element.waypoints; } },{"../../util/SvgTransformUtil":408,"min-dash":505,"tiny-svg":535}],367:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getDirection = getDirection; exports.resizeBounds = resizeBounds; /** * Get Resize direction given axis + offset * * @param {String} axis (x|y) * @param {Number} offset * * @return {String} (e|w|n|s) */ function getDirection(axis, offset) { if (axis === 'x') { if (offset > 0) { return 'e'; } if (offset < 0) { return 'w'; } } if (axis === 'y') { if (offset > 0) { return 's'; } if (offset < 0) { return 'n'; } } return null; } /** * Resize the given bounds by the specified delta from a given anchor point. * * @param {Bounds} bounds the bounding box that should be resized * @param {String} direction in which the element is resized (n, s, e, w) * @param {Point} delta of the resize operation * * @return {Bounds} resized bounding box */ function resizeBounds(bounds, direction, delta) { var dx = delta.x, dy = delta.y; switch (direction) { case 'n': return { x: bounds.x, y: bounds.y + dy, width: bounds.width, height: bounds.height - dy }; case 's': return { x: bounds.x, y: bounds.y, width: bounds.width, height: bounds.height + dy }; case 'w': return { x: bounds.x + dx, y: bounds.y, width: bounds.width - dx, height: bounds.height }; case 'e': return { x: bounds.x, y: bounds.y, width: bounds.width + dx, height: bounds.height }; default: throw new Error('unrecognized direction: ' + direction); } } },{}],368:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _dragging = require('../dragging'); var _dragging2 = _interopRequireDefault(_dragging); var _rules = require('../rules'); var _rules2 = _interopRequireDefault(_rules); var _toolManager = require('../tool-manager'); var _toolManager2 = _interopRequireDefault(_toolManager); var _previewSupport = require('../preview-support'); var _previewSupport2 = _interopRequireDefault(_previewSupport); var _SpaceTool = require('./SpaceTool'); var _SpaceTool2 = _interopRequireDefault(_SpaceTool); var _SpaceToolPreview = require('./SpaceToolPreview'); var _SpaceToolPreview2 = _interopRequireDefault(_SpaceToolPreview); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['spaceToolPreview'], __depends__: [_dragging2.default, _rules2.default, _toolManager2.default, _previewSupport2.default], spaceTool: ['type', _SpaceTool2.default], spaceToolPreview: ['type', _SpaceToolPreview2.default] }; },{"../dragging":286,"../preview-support":345,"../rules":355,"../tool-manager":370,"./SpaceTool":365,"./SpaceToolPreview":366}],369:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ToolManager; var _minDash = require('min-dash'); var _minDom = require('min-dom'); var LOW_PRIORITY = 250; /** * The tool manager acts as middle-man between the available tool's and the Palette, * it takes care of making sure that the correct active state is set. * * @param {Object} eventBus * @param {Object} dragging */ function ToolManager(eventBus, dragging) { this._eventBus = eventBus; this._dragging = dragging; this._tools = []; this._active = null; } ToolManager.$inject = ['eventBus', 'dragging']; ToolManager.prototype.registerTool = function (name, events) { var tools = this._tools; if (!events) { throw new Error('A tool has to be registered with it\'s "events"'); } tools.push(name); this.bindEvents(name, events); }; ToolManager.prototype.isActive = function (tool) { return tool && this._active === tool; }; ToolManager.prototype.length = function (tool) { return this._tools.length; }; ToolManager.prototype.setActive = function (tool) { var eventBus = this._eventBus; if (this._active !== tool) { this._active = tool; eventBus.fire('tool-manager.update', { tool: tool }); } }; ToolManager.prototype.bindEvents = function (name, events) { var eventBus = this._eventBus, dragging = this._dragging; var eventsToRegister = []; eventBus.on(events.tool + '.init', function (event) { var context = event.context; // Active tools that want to reactivate themselves must do this explicitly if (!context.reactivate && this.isActive(name)) { this.setActive(null); dragging.cancel(); return; } this.setActive(name); }, this); // Todo[ricardo]: add test cases (0, _minDash.forEach)(events, function (event) { eventsToRegister.push(event + '.ended'); eventsToRegister.push(event + '.canceled'); }); eventBus.on(eventsToRegister, LOW_PRIORITY, function (event) { var originalEvent = event.originalEvent; // We defer the de-activation of the tool to the .activate phase, // so we're able to check if we want to toggle off the current // active tool or switch to a new one if (!this._active) { return; } if (originalEvent && (0, _minDom.closest)(originalEvent.target, '.group[data-group="tools"]')) { return; } this.setActive(null); }, this); }; },{"min-dash":505,"min-dom":506}],370:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _dragging = require('../dragging'); var _dragging2 = _interopRequireDefault(_dragging); var _ToolManager = require('./ToolManager'); var _ToolManager2 = _interopRequireDefault(_ToolManager); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_dragging2.default], __init__: ['toolManager'], toolManager: ['type', _ToolManager2.default] }; },{"../dragging":286,"./ToolManager":369}],371:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Tooltips; var _minDash = require('min-dash'); var _minDom = require('min-dom'); var _IdGenerator = require('../../util/IdGenerator'); var _IdGenerator2 = _interopRequireDefault(_IdGenerator); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // document wide unique tooltip ids var ids = new _IdGenerator2.default('tt'); function createRoot(parentNode) { var root = (0, _minDom.domify)('
'); parentNode.insertBefore(root, parentNode.firstChild); return root; } function setPosition(el, x, y) { (0, _minDash.assign)(el.style, { left: x + 'px', top: y + 'px' }); } function setVisible(el, visible) { el.style.display = visible === false ? 'none' : ''; } var tooltipClass = 'djs-tooltip', tooltipSelector = '.' + tooltipClass; /** * A service that allows users to render tool tips on the diagram. * * The tooltip service will take care of updating the tooltip positioning * during navigation + zooming. * * @example * * ```javascript * * // add a pink badge on the top left of the shape * tooltips.add({ * position: { * x: 50, * y: 100 * }, * html: '
0
' * }); * * // or with optional life span * tooltips.add({ * position: { * top: -5, * left: -5 * }, * html: '
0
', * ttl: 2000 * }); * * // remove a tool tip * var id = tooltips.add(...); * tooltips.remove(id); * ``` * * @param {EventBus} eventBus * @param {Canvas} canvas */ function Tooltips(eventBus, canvas) { this._eventBus = eventBus; this._canvas = canvas; this._ids = ids; this._tooltipDefaults = { show: { minZoom: 0.7, maxZoom: 5.0 } }; /** * Mapping tooltipId -> tooltip */ this._tooltips = {}; // root html element for all tooltips this._tooltipRoot = createRoot(canvas.getContainer()); var self = this; _minDom.delegate.bind(this._tooltipRoot, tooltipSelector, 'mousedown', function (event) { event.stopPropagation(); }); _minDom.delegate.bind(this._tooltipRoot, tooltipSelector, 'mouseover', function (event) { self.trigger('mouseover', event); }); _minDom.delegate.bind(this._tooltipRoot, tooltipSelector, 'mouseout', function (event) { self.trigger('mouseout', event); }); this._init(); } Tooltips.$inject = ['eventBus', 'canvas']; /** * Adds a HTML tooltip to the diagram * * @param {Object} tooltip the tooltip configuration * * @param {String|DOMElement} tooltip.html html element to use as an tooltip * @param {Object} [tooltip.show] show configuration * @param {Number} [tooltip.show.minZoom] minimal zoom level to show the tooltip * @param {Number} [tooltip.show.maxZoom] maximum zoom level to show the tooltip * @param {Object} tooltip.position where to attach the tooltip * @param {Number} [tooltip.position.left] relative to element bbox left attachment * @param {Number} [tooltip.position.top] relative to element bbox top attachment * @param {Number} [tooltip.position.bottom] relative to element bbox bottom attachment * @param {Number} [tooltip.position.right] relative to element bbox right attachment * @param {Number} [tooltip.timeout=-1] * * @return {String} id that may be used to reference the tooltip for update or removal */ Tooltips.prototype.add = function (tooltip) { if (!tooltip.position) { throw new Error('must specifiy tooltip position'); } if (!tooltip.html) { throw new Error('must specifiy tooltip html'); } var id = this._ids.next(); tooltip = (0, _minDash.assign)({}, this._tooltipDefaults, tooltip, { id: id }); this._addTooltip(tooltip); if (tooltip.timeout) { this.setTimeout(tooltip); } return id; }; Tooltips.prototype.trigger = function (action, event) { var node = event.delegateTarget || event.target; var tooltip = this.get((0, _minDom.attr)(node, 'data-tooltip-id')); if (!tooltip) { return; } if (action === 'mouseover' && tooltip.timeout) { this.clearTimeout(tooltip); } if (action === 'mouseout' && tooltip.timeout) { // cut timeout after mouse out tooltip.timeout = 1000; this.setTimeout(tooltip); } }; /** * Get a tooltip with the given id * * @param {String} id */ Tooltips.prototype.get = function (id) { if (typeof id !== 'string') { id = id.id; } return this._tooltips[id]; }; Tooltips.prototype.clearTimeout = function (tooltip) { tooltip = this.get(tooltip); if (!tooltip) { return; } var removeTimer = tooltip.removeTimer; if (removeTimer) { clearTimeout(removeTimer); tooltip.removeTimer = null; } }; Tooltips.prototype.setTimeout = function (tooltip) { tooltip = this.get(tooltip); if (!tooltip) { return; } this.clearTimeout(tooltip); var self = this; tooltip.removeTimer = setTimeout(function () { self.remove(tooltip); }, tooltip.timeout); }; /** * Remove an tooltip with the given id * * @param {String} id */ Tooltips.prototype.remove = function (id) { var tooltip = this.get(id); if (tooltip) { (0, _minDom.remove)(tooltip.html); (0, _minDom.remove)(tooltip.htmlContainer); delete tooltip.htmlContainer; delete this._tooltips[tooltip.id]; } }; Tooltips.prototype.show = function () { setVisible(this._tooltipRoot); }; Tooltips.prototype.hide = function () { setVisible(this._tooltipRoot, false); }; Tooltips.prototype._updateRoot = function (viewbox) { var a = viewbox.scale || 1; var d = viewbox.scale || 1; var matrix = 'matrix(' + a + ',0,0,' + d + ',' + -1 * viewbox.x * a + ',' + -1 * viewbox.y * d + ')'; this._tooltipRoot.style.transform = matrix; this._tooltipRoot.style['-ms-transform'] = matrix; }; Tooltips.prototype._addTooltip = function (tooltip) { var id = tooltip.id, html = tooltip.html, htmlContainer, tooltipRoot = this._tooltipRoot; // unwrap jquery (for those who need it) if (html.get && html.constructor.prototype.jquery) { html = html.get(0); } // create proper html elements from // tooltip HTML strings if ((0, _minDash.isString)(html)) { html = (0, _minDom.domify)(html); } htmlContainer = (0, _minDom.domify)('
'); htmlContainer.appendChild(html); if (tooltip.type) { (0, _minDom.classes)(htmlContainer).add('djs-tooltip-' + tooltip.type); } if (tooltip.className) { (0, _minDom.classes)(htmlContainer).add(tooltip.className); } tooltip.htmlContainer = htmlContainer; tooltipRoot.appendChild(htmlContainer); this._tooltips[id] = tooltip; this._updateTooltip(tooltip); }; Tooltips.prototype._updateTooltip = function (tooltip) { var position = tooltip.position, htmlContainer = tooltip.htmlContainer; // update overlay html based on tooltip x, y setPosition(htmlContainer, position.x, position.y); }; Tooltips.prototype._updateTooltipVisibilty = function (viewbox) { (0, _minDash.forEach)(this._tooltips, function (tooltip) { var show = tooltip.show, htmlContainer = tooltip.htmlContainer, visible = true; if (show) { if (show.minZoom > viewbox.scale || show.maxZoom < viewbox.scale) { visible = false; } setVisible(htmlContainer, visible); } }); }; Tooltips.prototype._init = function () { var self = this; // scroll/zoom integration function updateViewbox(viewbox) { self._updateRoot(viewbox); self._updateTooltipVisibilty(viewbox); self.show(); } this._eventBus.on('canvas.viewbox.changing', function (event) { self.hide(); }); this._eventBus.on('canvas.viewbox.changed', function (event) { updateViewbox(event.viewbox); }); }; },{"../../util/IdGenerator":400,"min-dash":505,"min-dom":506}],372:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _Tooltips = require('./Tooltips'); var _Tooltips2 = _interopRequireDefault(_Tooltips); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['tooltips'], tooltips: ['type', _Tooltips2.default] }; },{"./Tooltips":371}],373:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = TouchFix; var _tinySvg = require('tiny-svg'); function TouchFix(canvas, eventBus) { var self = this; eventBus.on('canvas.init', function (e) { self.addBBoxMarker(e.svg); }); } TouchFix.$inject = ['canvas', 'eventBus']; /** * Safari mobile (iOS 7) does not fire touchstart event in element * if there is no shape between 0,0 and viewport elements origin. * * So touchstart event is only fired when the element was hit. * Putting an element over and below the 'viewport' fixes that behavior. */ TouchFix.prototype.addBBoxMarker = function (svg) { var markerStyle = { fill: 'none', class: 'outer-bound-marker' }; var rect1 = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(rect1, { x: -10000, y: 10000, width: 10, height: 10 }); (0, _tinySvg.attr)(rect1, markerStyle); (0, _tinySvg.append)(svg, rect1); var rect2 = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(rect2, { x: 10000, y: 10000, width: 10, height: 10 }); (0, _tinySvg.attr)(rect2, markerStyle); (0, _tinySvg.append)(svg, rect2); }; },{"tiny-svg":535}],374:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = TouchInteractionEvents; var _minDash = require('min-dash'); var _minDom = require('min-dom'); var _hammerjs = require('hammerjs'); var _hammerjs2 = _interopRequireDefault(_hammerjs); var _Event = require('../../util/Event'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var MIN_ZOOM = 0.2, MAX_ZOOM = 4; var mouseEvents = ['mousedown', 'mouseup', 'mouseover', 'mouseout', 'click', 'dblclick']; function log() { // console.log.apply(console, arguments); } function get(service, injector) { return injector.get(service, false); } function stopEvent(event) { event.preventDefault(); event.stopPropagation(); if (typeof event.stopImmediatePropagation === 'function') { event.stopImmediatePropagation(); } } function createTouchRecognizer(node) { function stopMouse(event) { (0, _minDash.forEach)(mouseEvents, function (e) { _minDom.event.bind(node, e, stopEvent, true); }); } function allowMouse(event) { setTimeout(function () { (0, _minDash.forEach)(mouseEvents, function (e) { _minDom.event.unbind(node, e, stopEvent, true); }); }, 500); } _minDom.event.bind(node, 'touchstart', stopMouse, true); _minDom.event.bind(node, 'touchend', allowMouse, true); _minDom.event.bind(node, 'touchcancel', allowMouse, true); // A touch event recognizer that handles // touch events only (we know, we can already handle // mouse events out of the box) var recognizer = new _hammerjs2.default.Manager(node, { inputClass: _hammerjs2.default.TouchInput, recognizers: [] }); var tap = new _hammerjs2.default.Tap(); var pan = new _hammerjs2.default.Pan({ threshold: 10 }); var press = new _hammerjs2.default.Press(); var pinch = new _hammerjs2.default.Pinch(); var doubleTap = new _hammerjs2.default.Tap({ event: 'doubletap', taps: 2 }); pinch.requireFailure(pan); pinch.requireFailure(press); recognizer.add([pan, press, pinch, doubleTap, tap]); recognizer.reset = function (force) { var recognizers = this.recognizers, session = this.session; if (session.stopped) { return; } log('recognizer', 'stop'); recognizer.stop(force); setTimeout(function () { var i, r; log('recognizer', 'reset'); for (i = 0; r = recognizers[i]; i++) { r.reset(); r.state = 8; // FAILED STATE } session.curRecognizer = null; }, 0); }; recognizer.on('hammer.input', function (event) { if (event.srcEvent.defaultPrevented) { recognizer.reset(true); } }); return recognizer; } /** * A plugin that provides touch events for elements. * * @param {EventBus} eventBus * @param {InteractionEvents} interactionEvents */ function TouchInteractionEvents(injector, canvas, eventBus, elementRegistry, interactionEvents) { // optional integrations var dragging = get('dragging', injector), move = get('move', injector), contextPad = get('contextPad', injector), palette = get('palette', injector); // the touch recognizer var recognizer; function handler(type) { return function (event) { log('element', type, event); interactionEvents.fire(type, event); }; } function getGfx(target) { var node = (0, _minDom.closest)(target, 'svg, .djs-element', true); return node; } function initEvents(svg) { // touch recognizer recognizer = createTouchRecognizer(svg); recognizer.on('doubletap', handler('element.dblclick')); recognizer.on('tap', handler('element.click')); function startGrabCanvas(event) { log('canvas', 'grab start'); var lx = 0, ly = 0; function update(e) { var dx = e.deltaX - lx, dy = e.deltaY - ly; canvas.scroll({ dx: dx, dy: dy }); lx = e.deltaX; ly = e.deltaY; } function end(e) { recognizer.off('panmove', update); recognizer.off('panend', end); recognizer.off('pancancel', end); log('canvas', 'grab end'); } recognizer.on('panmove', update); recognizer.on('panend', end); recognizer.on('pancancel', end); } function startGrab(event) { var gfx = getGfx(event.target), element = gfx && elementRegistry.get(gfx); // recognizer if (move && canvas.getRootElement() !== element) { log('element', 'move start', element, event, true); return move.start(event, element, true); } else { startGrabCanvas(event); } } function startZoom(e) { log('canvas', 'zoom start'); var zoom = canvas.zoom(), mid = e.center; function update(e) { var ratio = 1 - (1 - e.scale) / 1.50, newZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, ratio * zoom)); canvas.zoom(newZoom, mid); stopEvent(e); } function end(e) { recognizer.off('pinchmove', update); recognizer.off('pinchend', end); recognizer.off('pinchcancel', end); recognizer.reset(true); log('canvas', 'zoom end'); } recognizer.on('pinchmove', update); recognizer.on('pinchend', end); recognizer.on('pinchcancel', end); } recognizer.on('panstart', startGrab); recognizer.on('press', startGrab); recognizer.on('pinchstart', startZoom); } if (dragging) { // simulate hover during dragging eventBus.on('drag.move', function (event) { var originalEvent = event.originalEvent; if (!originalEvent || originalEvent instanceof MouseEvent) { return; } var position = (0, _Event.toPoint)(originalEvent); // this gets really expensive ... var node = document.elementFromPoint(position.x, position.y), gfx = getGfx(node), element = gfx && elementRegistry.get(gfx); if (element !== event.hover) { if (event.hover) { dragging.out(event); } if (element) { dragging.hover({ element: element, gfx: gfx }); event.hover = element; event.hoverGfx = gfx; } } }); } if (contextPad) { eventBus.on('contextPad.create', function (event) { var node = event.pad.html; // touch recognizer var padRecognizer = createTouchRecognizer(node); padRecognizer.on('panstart', function (event) { log('context-pad', 'panstart', event); contextPad.trigger('dragstart', event, true); }); padRecognizer.on('press', function (event) { log('context-pad', 'press', event); contextPad.trigger('dragstart', event, true); }); padRecognizer.on('tap', function (event) { log('context-pad', 'tap', event); contextPad.trigger('click', event); }); }); } if (palette) { eventBus.on('palette.create', function (event) { var node = event.container; // touch recognizer var padRecognizer = createTouchRecognizer(node); padRecognizer.on('panstart', function (event) { log('palette', 'panstart', event); palette.trigger('dragstart', event, true); }); padRecognizer.on('press', function (event) { log('palette', 'press', event); palette.trigger('dragstart', event, true); }); padRecognizer.on('tap', function (event) { log('palette', 'tap', event); palette.trigger('click', event); }); }); } eventBus.on('canvas.init', function (event) { initEvents(event.svg); }); } TouchInteractionEvents.$inject = ['injector', 'canvas', 'eventBus', 'elementRegistry', 'interactionEvents', 'touchFix']; },{"../../util/Event":397,"hammerjs":412,"min-dash":505,"min-dom":506}],375:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _interactionEvents = require('../interaction-events'); var _interactionEvents2 = _interopRequireDefault(_interactionEvents); var _TouchInteractionEvents = require('./TouchInteractionEvents'); var _TouchInteractionEvents2 = _interopRequireDefault(_TouchInteractionEvents); var _TouchFix = require('./TouchFix'); var _TouchFix2 = _interopRequireDefault(_TouchFix); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_interactionEvents2.default], __init__: ['touchInteractionEvents'], touchInteractionEvents: ['type', _TouchInteractionEvents2.default], touchFix: ['type', _TouchFix2.default] }; },{"../interaction-events":294,"./TouchFix":373,"./TouchInteractionEvents":374}],376:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _translate = require('./translate'); var _translate2 = _interopRequireDefault(_translate); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { translate: ['value', _translate2.default] }; },{"./translate":377}],377:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = translate; /** * A simple translation stub to be used for multi-language support * in diagrams. Can be easily replaced with a more sophisticated * solution. * * @example * * // use it inside any diagram component by injecting `translate`. * * function MyService(translate) { * alert(translate('HELLO {you}', { you: 'You!' })); * } * * @param {String} template to interpolate * @param {Object} [replacements] a map with substitutes * * @return {String} the translated string */ function translate(template, replacements) { replacements = replacements || {}; return template.replace(/{([^}]+)}/g, function (_, key) { return replacements[key] || '{' + key + '}'; }); } },{}],378:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BaseLayouter; var _LayoutUtil = require('./LayoutUtil'); /** * A base connection layouter implementation * that layouts the connection by directly connecting * mid(source) + mid(target). */ function BaseLayouter() {} /** * Return the new layouted waypoints for the given connection. * * The connection passed is still unchanged; you may figure out about * the new connection start / end via the layout hints provided. * * @param {djs.model.Connection} connection * @param {Object} [hints] * @param {Point} [hints.connectionStart] * @param {Point} [hints.connectionEnd] * * @return {Array} the layouted connection waypoints */ BaseLayouter.prototype.layoutConnection = function (connection, hints) { hints = hints || {}; return [hints.connectionStart || (0, _LayoutUtil.getMid)(connection.source), hints.connectionEnd || (0, _LayoutUtil.getMid)(connection.target)]; }; },{"./LayoutUtil":380}],379:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CroppingConnectionDocking; var _minDash = require('min-dash'); var _LayoutUtil = require('./LayoutUtil'); function dockingToPoint(docking) { // use the dockings actual point and // retain the original docking return (0, _minDash.assign)({ original: docking.point.original || docking.point }, docking.actual); } /** * A {@link ConnectionDocking} that crops connection waypoints based on * the path(s) of the connection source and target. * * @param {djs.core.ElementRegistry} elementRegistry */ function CroppingConnectionDocking(elementRegistry, graphicsFactory) { this._elementRegistry = elementRegistry; this._graphicsFactory = graphicsFactory; } CroppingConnectionDocking.$inject = ['elementRegistry', 'graphicsFactory']; /** * @inheritDoc ConnectionDocking#getCroppedWaypoints */ CroppingConnectionDocking.prototype.getCroppedWaypoints = function (connection, source, target) { source = source || connection.source; target = target || connection.target; var sourceDocking = this.getDockingPoint(connection, source, true), targetDocking = this.getDockingPoint(connection, target); var croppedWaypoints = connection.waypoints.slice(sourceDocking.idx + 1, targetDocking.idx); croppedWaypoints.unshift(dockingToPoint(sourceDocking)); croppedWaypoints.push(dockingToPoint(targetDocking)); return croppedWaypoints; }; /** * Return the connection docking point on the specified shape * * @inheritDoc ConnectionDocking#getDockingPoint */ CroppingConnectionDocking.prototype.getDockingPoint = function (connection, shape, dockStart) { var waypoints = connection.waypoints, dockingIdx, dockingPoint, croppedPoint; dockingIdx = dockStart ? 0 : waypoints.length - 1; dockingPoint = waypoints[dockingIdx]; croppedPoint = this._getIntersection(shape, connection, dockStart); return { point: dockingPoint, actual: croppedPoint || dockingPoint, idx: dockingIdx }; }; // helpers ////////////////////// CroppingConnectionDocking.prototype._getIntersection = function (shape, connection, takeFirst) { var shapePath = this._getShapePath(shape), connectionPath = this._getConnectionPath(connection); return (0, _LayoutUtil.getElementLineIntersection)(shapePath, connectionPath, takeFirst); }; CroppingConnectionDocking.prototype._getConnectionPath = function (connection) { return this._graphicsFactory.getConnectionPath(connection); }; CroppingConnectionDocking.prototype._getShapePath = function (shape) { return this._graphicsFactory.getShapePath(shape); }; CroppingConnectionDocking.prototype._getGfx = function (element) { return this._elementRegistry.getGraphics(element); }; },{"./LayoutUtil":380,"min-dash":505}],380:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.roundBounds = roundBounds; exports.roundPoint = roundPoint; exports.asTRBL = asTRBL; exports.asBounds = asBounds; exports.getMid = getMid; exports.getOrientation = getOrientation; exports.getElementLineIntersection = getElementLineIntersection; exports.getIntersections = getIntersections; var _minDash = require('min-dash'); var _Geometry = require('../util/Geometry'); var _pathIntersection = require('path-intersection'); var _pathIntersection2 = _interopRequireDefault(_pathIntersection); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function roundBounds(bounds) { return { x: Math.round(bounds.x), y: Math.round(bounds.y), width: Math.round(bounds.width), height: Math.round(bounds.height) }; } function roundPoint(point) { return { x: Math.round(point.x), y: Math.round(point.y) }; } /** * Convert the given bounds to a { top, left, bottom, right } descriptor. * * @param {Bounds|Point} bounds * * @return {Object} */ function asTRBL(bounds) { return { top: bounds.y, right: bounds.x + (bounds.width || 0), bottom: bounds.y + (bounds.height || 0), left: bounds.x }; } /** * Convert a { top, left, bottom, right } to an objects bounds. * * @param {Object} trbl * * @return {Bounds} */ function asBounds(trbl) { return { x: trbl.left, y: trbl.top, width: trbl.right - trbl.left, height: trbl.bottom - trbl.top }; } /** * Get the mid of the given bounds or point. * * @param {Bounds|Point} bounds * * @return {Point} */ function getMid(bounds) { return roundPoint({ x: bounds.x + (bounds.width || 0) / 2, y: bounds.y + (bounds.height || 0) / 2 }); } // orientation utils ////////////////////// /** * Get orientation of the given rectangle with respect to * the reference rectangle. * * A padding (positive or negative) may be passed to influence * horizontal / vertical orientation and intersection. * * @param {Bounds} rect * @param {Bounds} reference * @param {Point|Number} padding * * @return {String} the orientation; one of top, top-left, left, ..., bottom, right or intersect. */ function getOrientation(rect, reference, padding) { padding = padding || 0; // make sure we can use an object, too // for individual { x, y } padding if (!(0, _minDash.isObject)(padding)) { padding = { x: padding, y: padding }; } var rectOrientation = asTRBL(rect), referenceOrientation = asTRBL(reference); var top = rectOrientation.bottom + padding.y <= referenceOrientation.top, right = rectOrientation.left - padding.x >= referenceOrientation.right, bottom = rectOrientation.top - padding.y >= referenceOrientation.bottom, left = rectOrientation.right + padding.x <= referenceOrientation.left; var vertical = top ? 'top' : bottom ? 'bottom' : null, horizontal = left ? 'left' : right ? 'right' : null; if (horizontal && vertical) { return vertical + '-' + horizontal; } else { return horizontal || vertical || 'intersect'; } } // intersection utils ////////////////////// /** * Get intersection between an element and a line path. * * @param {PathDef} elementPath * @param {PathDef} linePath * @param {Boolean} cropStart crop from start or end * * @return {Point} */ function getElementLineIntersection(elementPath, linePath, cropStart) { var intersections = getIntersections(elementPath, linePath); // recognize intersections // only one -> choose // two close together -> choose first // two or more distinct -> pull out appropriate one // none -> ok (fallback to point itself) if (intersections.length === 1) { return roundPoint(intersections[0]); } else if (intersections.length === 2 && (0, _Geometry.pointDistance)(intersections[0], intersections[1]) < 1) { return roundPoint(intersections[0]); } else if (intersections.length > 1) { // sort by intersections based on connection segment + // distance from start intersections = (0, _minDash.sortBy)(intersections, function (i) { var distance = Math.floor(i.t2 * 100) || 1; distance = 100 - distance; distance = (distance < 10 ? '0' : '') + distance; // create a sort string that makes sure we sort // line segment ASC + line segment position DESC (for cropStart) // line segment ASC + line segment position ASC (for cropEnd) return i.segment2 + '#' + distance; }); return roundPoint(intersections[cropStart ? 0 : intersections.length - 1]); } return null; } function getIntersections(a, b) { return (0, _pathIntersection2.default)(a, b); } },{"../util/Geometry":398,"min-dash":505,"path-intersection":523}],381:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.connectPoints = connectPoints; exports.connectRectangles = connectRectangles; exports.repairConnection = repairConnection; exports.layoutStraight = layoutStraight; exports._repairConnectionSide = _repairConnectionSide; exports.withoutRedundantPoints = withoutRedundantPoints; var _minDash = require('min-dash'); var _LayoutUtil = require('./LayoutUtil'); var _Geometry = require('../util/Geometry'); var MIN_SEGMENT_LENGTH = 20, POINT_ORIENTATION_PADDING = 5; var round = Math.round; var INTERSECTION_THRESHOLD = 20, ORIENTATION_THRESHOLD = { 'h:h': 20, 'v:v': 20, 'h:v': -10, 'v:h': -10 }; function needsTurn(orientation, startDirection) { return !{ t: /top/, r: /right/, b: /bottom/, l: /left/, h: /./, v: /./ }[startDirection].test(orientation); } function canLayoutStraight(direction, targetOrientation) { return { t: /top/, r: /right/, b: /bottom/, l: /left/, h: /left|right/, v: /top|bottom/ }[direction].test(targetOrientation); } function getSegmentBendpoints(a, b, directions) { var orientation = (0, _LayoutUtil.getOrientation)(b, a, POINT_ORIENTATION_PADDING); var startDirection = directions.split(':')[0]; var xmid = round((b.x - a.x) / 2 + a.x), ymid = round((b.y - a.y) / 2 + a.y); var segmentEnd, segmentDirections; var layoutStraight = canLayoutStraight(startDirection, orientation), layoutHorizontal = /h|r|l/.test(startDirection), layoutTurn = false; var turnNextDirections = false; if (layoutStraight) { segmentEnd = layoutHorizontal ? { x: xmid, y: a.y } : { x: a.x, y: ymid }; segmentDirections = layoutHorizontal ? 'h:h' : 'v:v'; } else { layoutTurn = needsTurn(orientation, startDirection); segmentDirections = layoutHorizontal ? 'h:v' : 'v:h'; if (layoutTurn) { if (layoutHorizontal) { turnNextDirections = ymid === a.y; segmentEnd = { x: a.x + MIN_SEGMENT_LENGTH * (/l/.test(startDirection) ? -1 : 1), y: turnNextDirections ? ymid + MIN_SEGMENT_LENGTH : ymid }; } else { turnNextDirections = xmid === a.x; segmentEnd = { x: turnNextDirections ? xmid + MIN_SEGMENT_LENGTH : xmid, y: a.y + MIN_SEGMENT_LENGTH * (/t/.test(startDirection) ? -1 : 1) }; } } else { segmentEnd = { x: xmid, y: ymid }; } } return { waypoints: getBendpoints(a, segmentEnd, segmentDirections).concat(segmentEnd), directions: segmentDirections, turnNextDirections: turnNextDirections }; } function getStartSegment(a, b, directions) { return getSegmentBendpoints(a, b, directions); } function getEndSegment(a, b, directions) { var invertedSegment = getSegmentBendpoints(b, a, invertDirections(directions)); return { waypoints: invertedSegment.waypoints.slice().reverse(), directions: invertDirections(invertedSegment.directions), turnNextDirections: invertedSegment.turnNextDirections }; } function getMidSegment(startSegment, endSegment) { var startDirection = startSegment.directions.split(':')[1], endDirection = endSegment.directions.split(':')[0]; if (startSegment.turnNextDirections) { startDirection = startDirection == 'h' ? 'v' : 'h'; } if (endSegment.turnNextDirections) { endDirection = endDirection == 'h' ? 'v' : 'h'; } var directions = startDirection + ':' + endDirection; var bendpoints = getBendpoints(startSegment.waypoints[startSegment.waypoints.length - 1], endSegment.waypoints[0], directions); return { waypoints: bendpoints, directions: directions }; } function invertDirections(directions) { return directions.split(':').reverse().join(':'); } /** * Handle simple layouts with maximum two bendpoints. */ function getSimpleBendpoints(a, b, directions) { var xmid = round((b.x - a.x) / 2 + a.x), ymid = round((b.y - a.y) / 2 + a.y); // one point, right or left from a if (directions === 'h:v') { return [{ x: b.x, y: a.y }]; } // one point, above or below a if (directions === 'v:h') { return [{ x: a.x, y: b.y }]; } // vertical segment between a and b if (directions === 'h:h') { return [{ x: xmid, y: a.y }, { x: xmid, y: b.y }]; } // horizontal segment between a and b if (directions === 'v:v') { return [{ x: a.x, y: ymid }, { x: b.x, y: ymid }]; } throw new Error('invalid directions: can only handle varians of [hv]:[hv]'); } /** * Returns the mid points for a manhattan connection between two points. * * @example h:h (horizontal:horizontal) * * [a]----[x] * | * [x]----[b] * * @example h:v (horizontal:vertical) * * [a]----[x] * | * [b] * * @example h:r (horizontal:right) * * [a]----[x] * | * [b]-[x] * * @param {Point} a * @param {Point} b * @param {String} directions * * @return {Array} */ function getBendpoints(a, b, directions) { directions = directions || 'h:h'; if (!isValidDirections(directions)) { throw new Error('unknown directions: <' + directions + '>: ' + 'must be specified as : ' + 'with start/end in { h,v,t,r,b,l }'); } // compute explicit directions, involving trbl dockings // using a three segmented layouting algorithm if (isExplicitDirections(directions)) { var startSegment = getStartSegment(a, b, directions), endSegment = getEndSegment(a, b, directions), midSegment = getMidSegment(startSegment, endSegment); return [].concat(startSegment.waypoints, midSegment.waypoints, endSegment.waypoints); } // handle simple [hv]:[hv] cases that can be easily computed return getSimpleBendpoints(a, b, directions); } /** * Create a connection between the two points according * to the manhattan layout (only horizontal and vertical) edges. * * @param {Point} a * @param {Point} b * * @param {String} [directions='h:h'] specifies manhattan directions for each point as {adirection}:{bdirection}. A directionfor a point is either `h` (horizontal) or `v` (vertical) * * @return {Array} */ function connectPoints(a, b, directions) { var points = getBendpoints(a, b, directions); points.unshift(a); points.push(b); return withoutRedundantPoints(points); } /** * Connect two rectangles using a manhattan layouted connection. * * @param {Bounds} source source rectangle * @param {Bounds} target target rectangle * @param {Point} [start] source docking * @param {Point} [end] target docking * * @param {Object} [hints] * @param {String} [hints.preserveDocking=source] preserve docking on selected side * @param {Array} [hints.preferredLayouts] * @param {Point|Boolean} [hints.connectionStart] whether the start changed * @param {Point|Boolean} [hints.connectionEnd] whether the end changed * * @return {Array} connection points */ function connectRectangles(source, target, start, end, hints) { var preferredLayouts = hints && hints.preferredLayouts || []; var preferredLayout = (0, _minDash.without)(preferredLayouts, 'straight')[0] || 'h:h'; var threshold = ORIENTATION_THRESHOLD[preferredLayout] || 0; var orientation = (0, _LayoutUtil.getOrientation)(source, target, threshold); var directions = getDirections(orientation, preferredLayout); start = start || (0, _LayoutUtil.getMid)(source); end = end || (0, _LayoutUtil.getMid)(target); var directionSplit = directions.split(':'); // compute actual docking points for start / end // this ensures we properly layout only parts of the // connection that lies in between the two rectangles var startDocking = getDockingPoint(start, source, directionSplit[0], invertOrientation(orientation)), endDocking = getDockingPoint(end, target, directionSplit[1], orientation); return connectPoints(startDocking, endDocking, directions); } /** * Repair the connection between two rectangles, of which one has been updated. * * @param {Bounds} source * @param {Bounds} target * @param {Point} [start] * @param {Point} [end] * @param {Array} waypoints * @param {Object} [hints] * @param {Array} [hints.preferredLayouts] list of preferred layouts * @param {Boolean} [hints.connectionStart] * @param {Boolean} [hints.connectionEnd] * * @return {Array} repaired waypoints */ function repairConnection(source, target, start, end, waypoints, hints) { if ((0, _minDash.isArray)(start)) { waypoints = start; hints = end; start = (0, _LayoutUtil.getMid)(source); end = (0, _LayoutUtil.getMid)(target); } hints = (0, _minDash.assign)({ preferredLayouts: [] }, hints); waypoints = waypoints || []; var preferredLayouts = hints.preferredLayouts, preferStraight = preferredLayouts.indexOf('straight') !== -1, repairedWaypoints; // just layout non-existing or simple connections // attempt to render straight lines, if required if (preferStraight) { // attempt to layout a straight line repairedWaypoints = layoutStraight(source, target, start, end, hints); } if (!repairedWaypoints) { // check if we layout from start or end if (hints.connectionEnd) { repairedWaypoints = _repairConnectionSide(target, source, end, waypoints.slice().reverse()); repairedWaypoints = repairedWaypoints && repairedWaypoints.reverse(); } else if (hints.connectionStart) { repairedWaypoints = _repairConnectionSide(source, target, start, waypoints); } else // or whether nothing seems to have changed if (waypoints && waypoints.length) { repairedWaypoints = waypoints; } } // simply reconnect if nothing else worked if (!repairedWaypoints) { repairedWaypoints = connectRectangles(source, target, start, end, hints); } return repairedWaypoints; } function inRange(a, start, end) { return a >= start && a <= end; } function isInRange(axis, a, b) { var size = { x: 'width', y: 'height' }; return inRange(a[axis], b[axis], b[axis] + b[size[axis]]); } /** * Layout a straight connection * * @param {Bounds} source * @param {Bounds} target * @param {Point} start * @param {Point} end * @param {Object} [hints] * * @return {Array} waypoints if straight layout worked */ function layoutStraight(source, target, start, end, hints) { var axis = {}, primaryAxis, orientation; orientation = (0, _LayoutUtil.getOrientation)(source, target); // only layout a straight connection if shapes are // horizontally or vertically aligned if (!/^(top|bottom|left|right)$/.test(orientation)) { return null; } if (/top|bottom/.test(orientation)) { primaryAxis = 'x'; } if (/left|right/.test(orientation)) { primaryAxis = 'y'; } if (hints.preserveDocking === 'target') { if (!isInRange(primaryAxis, end, source)) { return null; } axis[primaryAxis] = end[primaryAxis]; return [{ x: axis.x !== undefined ? axis.x : start.x, y: axis.y !== undefined ? axis.y : start.y, original: { x: axis.x !== undefined ? axis.x : start.x, y: axis.y !== undefined ? axis.y : start.y } }, { x: end.x, y: end.y }]; } else { if (!isInRange(primaryAxis, start, target)) { return null; } axis[primaryAxis] = start[primaryAxis]; return [{ x: start.x, y: start.y }, { x: axis.x !== undefined ? axis.x : end.x, y: axis.y !== undefined ? axis.y : end.y, original: { x: axis.x !== undefined ? axis.x : end.x, y: axis.y !== undefined ? axis.y : end.y } }]; } } /** * Repair a connection from one side that moved. * * @param {Bounds} moved * @param {Bounds} other * @param {Point} newDocking * @param {Array} points originalPoints from moved to other * * @return {Array} the repaired points between the two rectangles */ function _repairConnectionSide(moved, other, newDocking, points) { function needsRelayout(moved, other, points) { if (points.length < 3) { return true; } if (points.length > 4) { return false; } // relayout if two points overlap // this is most likely due to return !!(0, _minDash.find)(points, function (p, idx) { var q = points[idx - 1]; return q && (0, _Geometry.pointDistance)(p, q) < 3; }); } function repairBendpoint(candidate, oldPeer, newPeer) { var alignment = (0, _Geometry.pointsAligned)(oldPeer, candidate); switch (alignment) { case 'v': // repair vertical alignment return { x: candidate.x, y: newPeer.y }; case 'h': // repair horizontal alignment return { x: newPeer.x, y: candidate.y }; } return { x: candidate.x, y: candidate.y }; } function removeOverlapping(points, a, b) { var i; for (i = points.length - 2; i !== 0; i--) { // intersects (?) break, remove all bendpoints up to this one and relayout if ((0, _Geometry.pointInRect)(points[i], a, INTERSECTION_THRESHOLD) || (0, _Geometry.pointInRect)(points[i], b, INTERSECTION_THRESHOLD)) { // return sliced old connection return points.slice(i); } } return points; } // (0) only repair what has layoutable bendpoints // (1) if only one bendpoint and on shape moved onto other shapes axis // (horizontally / vertically), relayout if (needsRelayout(moved, other, points)) { return null; } var oldDocking = points[0], newPoints = points.slice(), slicedPoints; // (2) repair only last line segment and only if it was layouted before newPoints[0] = newDocking; newPoints[1] = repairBendpoint(newPoints[1], oldDocking, newDocking); // (3) if shape intersects with any bendpoint after repair, // remove all segments up to this bendpoint and repair from there slicedPoints = removeOverlapping(newPoints, moved, other); if (slicedPoints !== newPoints) { return _repairConnectionSide(moved, other, newDocking, slicedPoints); } return newPoints; } /** * Returns the manhattan directions connecting two rectangles * with the given orientation. * * Will always return the default layout, if it is specific * regarding sides already (trbl). * * @example * * getDirections('top'); // -> 'v:v' * getDirections('intersect'); // -> 't:t' * * getDirections('top-right', 'v:h'); // -> 'v:h' * getDirections('top-right', 'h:h'); // -> 'h:h' * * * @param {String} orientation * @param {String} defaultLayout * * @return {String} */ function getDirections(orientation, defaultLayout) { // don't override specific trbl directions if (isExplicitDirections(defaultLayout)) { return defaultLayout; } switch (orientation) { case 'intersect': return 't:t'; case 'top': case 'bottom': return 'v:v'; case 'left': case 'right': return 'h:h'; // 'top-left' // 'top-right' // 'bottom-left' // 'bottom-right' default: return defaultLayout; } } function isValidDirections(directions) { return directions && /^h|v|t|r|b|l:h|v|t|r|b|l$/.test(directions); } function isExplicitDirections(directions) { return directions && /t|r|b|l/.test(directions); } function invertOrientation(orientation) { return { 'top': 'bottom', 'bottom': 'top', 'left': 'right', 'right': 'left', 'top-left': 'bottom-right', 'bottom-right': 'top-left', 'top-right': 'bottom-left', 'bottom-left': 'top-right' }[orientation]; } function getDockingPoint(point, rectangle, dockingDirection, targetOrientation) { // ensure we end up with a specific docking direction // based on the targetOrientation, if is being passed if (dockingDirection === 'h') { dockingDirection = /left/.test(targetOrientation) ? 'l' : 'r'; } if (dockingDirection === 'v') { dockingDirection = /top/.test(targetOrientation) ? 't' : 'b'; } if (dockingDirection === 't') { return { original: point, x: point.x, y: rectangle.y }; } if (dockingDirection === 'r') { return { original: point, x: rectangle.x + rectangle.width, y: point.y }; } if (dockingDirection === 'b') { return { original: point, x: point.x, y: rectangle.y + rectangle.height }; } if (dockingDirection === 'l') { return { original: point, x: rectangle.x, y: point.y }; } throw new Error('unexpected dockingDirection: <' + dockingDirection + '>'); } /** * Return list of waypoints with redundant ones filtered out. * * @example * * Original points: * * [x] ----- [x] ------ [x] * | * [x] ----- [x] - [x] * * Filtered: * * [x] ---------------- [x] * | * [x] ----------- [x] * * @param {Array} waypoints * * @return {Array} */ function withoutRedundantPoints(waypoints) { return waypoints.reduce(function (points, p, idx) { var previous = points[points.length - 1], next = waypoints[idx + 1]; if (!(0, _Geometry.pointsOnLine)(previous, next, p, 0)) { points.push(p); } return points; }, []); } },{"../util/Geometry":398,"./LayoutUtil":380,"min-dash":505}],382:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.Base = Base; exports.Shape = Shape; exports.Root = Root; exports.Label = Label; exports.Connection = Connection; exports.create = create; var _minDash = require('min-dash'); var _inherits = require('inherits'); var _inherits2 = _interopRequireDefault(_inherits); var _objectRefs = require('object-refs'); var _objectRefs2 = _interopRequireDefault(_objectRefs); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var parentRefs = new _objectRefs2.default({ name: 'children', enumerable: true, collection: true }, { name: 'parent' }), labelRefs = new _objectRefs2.default({ name: 'labels', enumerable: true, collection: true }, { name: 'labelTarget' }), attacherRefs = new _objectRefs2.default({ name: 'attachers', collection: true }, { name: 'host' }), outgoingRefs = new _objectRefs2.default({ name: 'outgoing', collection: true }, { name: 'source' }), incomingRefs = new _objectRefs2.default({ name: 'incoming', collection: true }, { name: 'target' }); /** * @namespace djs.model */ /** * @memberOf djs.model */ /** * The basic graphical representation * * @class * * @abstract */ function Base() { /** * The object that backs up the shape * * @name Base#businessObject * @type Object */ Object.defineProperty(this, 'businessObject', { writable: true }); /** * Single label support, will mapped to multi label array * * @name Base#label * @type Object */ Object.defineProperty(this, 'label', { get: function get() { return this.labels[0]; }, set: function set(newLabel) { var label = this.label, labels = this.labels; if (!newLabel && label) { labels.remove(label); } else { labels.add(newLabel, 0); } } }); /** * The parent shape * * @name Base#parent * @type Shape */ parentRefs.bind(this, 'parent'); /** * The list of labels * * @name Base#labels * @type Label */ labelRefs.bind(this, 'labels'); /** * The list of outgoing connections * * @name Base#outgoing * @type Array */ outgoingRefs.bind(this, 'outgoing'); /** * The list of incoming connections * * @name Base#incoming * @type Array */ incomingRefs.bind(this, 'incoming'); } /** * A graphical object * * @class * @constructor * * @extends Base */ function Shape() { Base.call(this); /** * The list of children * * @name Shape#children * @type Array */ parentRefs.bind(this, 'children'); /** * @name Shape#host * @type Shape */ attacherRefs.bind(this, 'host'); /** * @name Shape#attachers * @type Shape */ attacherRefs.bind(this, 'attachers'); } (0, _inherits2.default)(Shape, Base); /** * A root graphical object * * @class * @constructor * * @extends Shape */ function Root() { Shape.call(this); } (0, _inherits2.default)(Root, Shape); /** * A label for an element * * @class * @constructor * * @extends Shape */ function Label() { Shape.call(this); /** * The labeled element * * @name Label#labelTarget * @type Base */ labelRefs.bind(this, 'labelTarget'); } (0, _inherits2.default)(Label, Shape); /** * A connection between two elements * * @class * @constructor * * @extends Base */ function Connection() { Base.call(this); /** * The element this connection originates from * * @name Connection#source * @type Base */ outgoingRefs.bind(this, 'source'); /** * The element this connection points to * * @name Connection#target * @type Base */ incomingRefs.bind(this, 'target'); } (0, _inherits2.default)(Connection, Base); var types = { connection: Connection, shape: Shape, label: Label, root: Root }; /** * Creates a new model element of the specified type * * @method create * * @example * * var shape1 = Model.create('shape', { x: 10, y: 10, width: 100, height: 100 }); * var shape2 = Model.create('shape', { x: 210, y: 210, width: 100, height: 100 }); * * var connection = Model.create('connection', { waypoints: [ { x: 110, y: 55 }, {x: 210, y: 55 } ] }); * * @param {String} type lower-cased model name * @param {Object} attrs attributes to initialize the new model instance with * * @return {Base} the new model instance */ function create(type, attrs) { var Type = types[type]; if (!Type) { throw new Error('unknown type: <' + type + '>'); } return (0, _minDash.assign)(new Type(), attrs); } },{"inherits":415,"min-dash":505,"object-refs":520}],383:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = KeyboardMove; var _minDash = require('min-dash'); var DEFAULT_CONFIG = { moveSpeed: 50, moveSpeedAccelerated: 200 }; /** * A feature that allows users to move the canvas using the keyboard. * * @param {Object} config * @param {Number} [config.moveSpeed=50] * @param {Number} [config.moveSpeedAccelerated=200] * @param {Keyboard} keyboard * @param {Canvas} canvas */ function KeyboardMove(config, keyboard, canvas) { var self = this; this._config = (0, _minDash.assign)({}, DEFAULT_CONFIG, config || {}); keyboard.addListener(arrowsListener); function arrowsListener(context) { var event = context.keyEvent, config = self._config; if (!keyboard.isCmd(event)) { return; } if (keyboard.isKey(['ArrowLeft', 'Left', 'ArrowUp', 'Up', 'ArrowDown', 'Down', 'ArrowRight', 'Right'], event)) { var speed = keyboard.isShift(event) ? config.moveSpeedAccelerated : config.moveSpeed; var direction; switch (event.key) { case 'ArrowLeft': case 'Left': direction = 'left'; break; case 'ArrowUp': case 'Up': direction = 'up'; break; case 'ArrowRight': case 'Right': direction = 'right'; break; case 'ArrowDown': case 'Down': direction = 'down'; break; } self.moveCanvas({ speed: speed, direction: direction }); return true; } } this.moveCanvas = function (opts) { var dx = 0, dy = 0, speed = opts.speed; var actualSpeed = speed / Math.min(Math.sqrt(canvas.viewbox().scale), 1); switch (opts.direction) { case 'left': // Left dx = actualSpeed; break; case 'up': // Up dy = actualSpeed; break; case 'right': // Right dx = -actualSpeed; break; case 'down': // Down dy = -actualSpeed; break; } canvas.scroll({ dx: dx, dy: dy }); }; } KeyboardMove.$inject = ['config.keyboardMove', 'keyboard', 'canvas']; },{"min-dash":505}],384:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _keyboard = require('../../features/keyboard'); var _keyboard2 = _interopRequireDefault(_keyboard); var _KeyboardMove = require('./KeyboardMove'); var _KeyboardMove2 = _interopRequireDefault(_KeyboardMove); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_keyboard2.default], __init__: ['keyboardMove'], keyboardMove: ['type', _KeyboardMove2.default] }; },{"../../features/keyboard":300,"./KeyboardMove":383}],385:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MoveCanvas; var _Cursor = require('../../util/Cursor'); var _ClickTrap = require('../../util/ClickTrap'); var _PositionUtil = require('../../util/PositionUtil'); var _minDom = require('min-dom'); var _Event = require('../../util/Event'); var THRESHOLD = 15; /** * Move the canvas via mouse. * * @param {EventBus} eventBus * @param {Canvas} canvas */ function MoveCanvas(eventBus, canvas) { var context; // listen for move on element mouse down; // allow others to hook into the event before us though // (dragging / element moving will do this) eventBus.on('element.mousedown', 500, function (e) { return handleStart(e.originalEvent); }); function handleMove(event) { var start = context.start, position = (0, _Event.toPoint)(event), delta = (0, _PositionUtil.delta)(position, start); if (!context.dragging && length(delta) > THRESHOLD) { context.dragging = true; (0, _ClickTrap.install)(eventBus); (0, _Cursor.set)('grab'); } if (context.dragging) { var lastPosition = context.last || context.start; delta = (0, _PositionUtil.delta)(position, lastPosition); canvas.scroll({ dx: delta.x, dy: delta.y }); context.last = position; } // prevent select event.preventDefault(); } function handleEnd(event) { _minDom.event.unbind(document, 'mousemove', handleMove); _minDom.event.unbind(document, 'mouseup', handleEnd); context = null; (0, _Cursor.unset)(); } function handleStart(event) { // event is already handled by '.djs-draggable' if ((0, _minDom.closest)(event.target, '.djs-draggable')) { return; } // reject non-left left mouse button or modifier key if (event.button || event.ctrlKey || event.shiftKey || event.altKey) { return; } context = { start: (0, _Event.toPoint)(event) }; _minDom.event.bind(document, 'mousemove', handleMove); _minDom.event.bind(document, 'mouseup', handleEnd); // we've handled the event return true; } } MoveCanvas.$inject = ['eventBus', 'canvas']; // helpers /////// function length(point) { return Math.sqrt(Math.pow(point.x, 2) + Math.pow(point.y, 2)); } },{"../../util/ClickTrap":392,"../../util/Cursor":395,"../../util/Event":397,"../../util/PositionUtil":405,"min-dom":506}],386:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _MoveCanvas = require('./MoveCanvas'); var _MoveCanvas2 = _interopRequireDefault(_MoveCanvas); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['moveCanvas'], moveCanvas: ['type', _MoveCanvas2.default] }; },{"./MoveCanvas":385}],387:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _touch = require('../../features/touch'); var _touch2 = _interopRequireDefault(_touch); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __depends__: [_touch2.default] }; },{"../../features/touch":375}],388:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ZoomScroll; var _minDom = require('min-dom'); var _ZoomUtil = require('./ZoomUtil'); var _Math = require('../../util/Math'); var _minDash = require('min-dash'); var sign = Math.sign || function (n) { return n >= 0 ? 1 : -1; }; var RANGE = { min: 0.2, max: 4 }, NUM_STEPS = 10; var DELTA_THRESHOLD = 0.1; var DEFAULT_SCALE = 0.75; /** * An implementation of zooming and scrolling within the * {@link Canvas} via the mouse wheel. * * Mouse wheel zooming / scrolling may be disabled using * the {@link toggle(enabled)} method. * * @param {Object} [config] * @param {Boolean} [config.enabled=true] default enabled state * @param {Number} [config.scale=.75] scroll sensivity * @param {EventBus} eventBus * @param {Canvas} canvas */ function ZoomScroll(config, eventBus, canvas) { config = config || {}; this._enabled = false; this._canvas = canvas; this._container = canvas._container; this._handleWheel = (0, _minDash.bind)(this._handleWheel, this); this._totalDelta = 0; this._scale = config.scale || DEFAULT_SCALE; var self = this; eventBus.on('canvas.init', function (e) { self._init(config.enabled !== false); }); } ZoomScroll.$inject = ['config.zoomScroll', 'eventBus', 'canvas']; ZoomScroll.prototype.scroll = function scroll(delta) { this._canvas.scroll(delta); }; ZoomScroll.prototype.reset = function reset() { this._canvas.zoom('fit-viewport'); }; /** * Zoom depending on delta. * * @param {number} delta - Zoom delta. * @param {Object} position - Zoom position. */ ZoomScroll.prototype.zoom = function zoom(delta, position) { // zoom with half the step size of stepZoom var stepSize = (0, _ZoomUtil.getStepSize)(RANGE, NUM_STEPS * 2); // add until threshold reached this._totalDelta += delta; if (Math.abs(this._totalDelta) > DELTA_THRESHOLD) { this._zoom(delta, position, stepSize); // reset this._totalDelta = 0; } }; ZoomScroll.prototype._handleWheel = function handleWheel(event) { // event is already handled by '.djs-scrollable' if ((0, _minDom.closest)(event.target, '.djs-scrollable', true)) { return; } var element = this._container; event.preventDefault(); // pinch to zoom is mapped to wheel + ctrlKey = true // in modern browsers (!) var isZoom = event.ctrlKey; var isHorizontalScroll = event.shiftKey; var factor = -1 * this._scale, delta; if (isZoom) { factor *= event.deltaMode === 0 ? 0.020 : 0.32; } else { factor *= event.deltaMode === 0 ? 1.0 : 16.0; } if (isZoom) { var elementRect = element.getBoundingClientRect(); var offset = { x: event.clientX - elementRect.left, y: event.clientY - elementRect.top }; delta = Math.sqrt(Math.pow(event.deltaY, 2) + Math.pow(event.deltaX, 2)) * sign(event.deltaY) * factor; // zoom in relative to diagram {x,y} coordinates this.zoom(delta, offset); } else { if (isHorizontalScroll) { delta = { dx: factor * event.deltaY, dy: 0 }; } else { delta = { dx: factor * event.deltaX, dy: factor * event.deltaY }; } this.scroll(delta); } }; /** * Zoom with fixed step size. * * @param {number} delta - Zoom delta (1 for zooming in, -1 for out). * @param {Object} position - Zoom position. */ ZoomScroll.prototype.stepZoom = function stepZoom(delta, position) { var stepSize = (0, _ZoomUtil.getStepSize)(RANGE, NUM_STEPS); this._zoom(delta, position, stepSize); }; /** * Zoom in/out given a step size. * * @param {number} delta - Zoom delta. Can be positive or negative. * @param {Object} position - Zoom position. * @param {number} stepSize - Step size. */ ZoomScroll.prototype._zoom = function (delta, position, stepSize) { var canvas = this._canvas; var direction = delta > 0 ? 1 : -1; var currentLinearZoomLevel = (0, _Math.log10)(canvas.zoom()); // snap to a proximate zoom step var newLinearZoomLevel = Math.round(currentLinearZoomLevel / stepSize) * stepSize; // increase or decrease one zoom step in the given direction newLinearZoomLevel += stepSize * direction; // calculate the absolute logarithmic zoom level based on the linear zoom level // (e.g. 2 for an absolute x2 zoom) var newLogZoomLevel = Math.pow(10, newLinearZoomLevel); canvas.zoom((0, _ZoomUtil.cap)(RANGE, newLogZoomLevel), position); }; /** * Toggle the zoom scroll ability via mouse wheel. * * @param {Boolean} [newEnabled] new enabled state */ ZoomScroll.prototype.toggle = function toggle(newEnabled) { var element = this._container; var handleWheel = this._handleWheel; var oldEnabled = this._enabled; if (typeof newEnabled === 'undefined') { newEnabled = !oldEnabled; } // only react on actual changes if (oldEnabled !== newEnabled) { // add or remove wheel listener based on // changed enabled state _minDom.event[newEnabled ? 'bind' : 'unbind'](element, 'wheel', handleWheel, false); } this._enabled = newEnabled; return newEnabled; }; ZoomScroll.prototype._init = function (newEnabled) { this.toggle(newEnabled); }; },{"../../util/Math":402,"./ZoomUtil":389,"min-dash":505,"min-dom":506}],389:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getStepSize = getStepSize; exports.cap = cap; var _Math = require('../../util/Math'); /** * Get step size for given range and number of steps. * * @param {Object} range - Range. * @param {number} range.min - Range minimum. * @param {number} range.max - Range maximum. */ function getStepSize(range, steps) { var minLinearRange = (0, _Math.log10)(range.min), maxLinearRange = (0, _Math.log10)(range.max); var absoluteLinearRange = Math.abs(minLinearRange) + Math.abs(maxLinearRange); return absoluteLinearRange / steps; } function cap(range, scale) { return Math.max(range.min, Math.min(range.max, scale)); } },{"../../util/Math":402}],390:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _ZoomScroll = require('./ZoomScroll'); var _ZoomScroll2 = _interopRequireDefault(_ZoomScroll); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = { __init__: ['zoomScroll'], zoomScroll: ['type', _ZoomScroll2.default] }; },{"./ZoomScroll":388}],391:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getNewAttachPoint = getNewAttachPoint; exports.getNewAttachShapeDelta = getNewAttachShapeDelta; var _LayoutUtil = require('../layout/LayoutUtil'); var _PositionUtil = require('./PositionUtil'); /** * Calculates the absolute point relative to the new element's position * * @param {point} point [absolute] * @param {bounds} oldBounds * @param {bounds} newBounds * * @return {point} point [absolute] */ function getNewAttachPoint(point, oldBounds, newBounds) { var oldCenter = (0, _PositionUtil.center)(oldBounds), newCenter = (0, _PositionUtil.center)(newBounds), oldDelta = (0, _PositionUtil.delta)(point, oldCenter); var newDelta = { x: oldDelta.x * (newBounds.width / oldBounds.width), y: oldDelta.y * (newBounds.height / oldBounds.height) }; return (0, _LayoutUtil.roundPoint)({ x: newCenter.x + newDelta.x, y: newCenter.y + newDelta.y }); } /** * Calculates the shape's delta relative to a new position * of a certain element's bounds * * @param {djs.model.Shape} point [absolute] * @param {bounds} oldBounds * @param {bounds} newBounds * * @return {delta} delta */ function getNewAttachShapeDelta(shape, oldBounds, newBounds) { var shapeCenter = (0, _PositionUtil.center)(shape), oldCenter = (0, _PositionUtil.center)(oldBounds), newCenter = (0, _PositionUtil.center)(newBounds), shapeDelta = (0, _PositionUtil.delta)(shape, shapeCenter), oldCenterDelta = (0, _PositionUtil.delta)(shapeCenter, oldCenter); var newCenterDelta = { x: oldCenterDelta.x * (newBounds.width / oldBounds.width), y: oldCenterDelta.y * (newBounds.height / oldBounds.height) }; var newShapeCenter = { x: newCenter.x + newCenterDelta.x, y: newCenter.y + newCenterDelta.y }; return (0, _LayoutUtil.roundPoint)({ x: newShapeCenter.x + shapeDelta.x - shape.x, y: newShapeCenter.y + shapeDelta.y - shape.y }); } },{"../layout/LayoutUtil":380,"./PositionUtil":405}],392:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.install = install; var TRAP_PRIORITY = 5000; /** * Installs a click trap that prevents a ghost click following a dragging operation. * * @return {Function} a function to immediately remove the installed trap. */ function install(eventBus, eventName) { eventName = eventName || 'element.click'; function trap() { return false; } eventBus.once(eventName, TRAP_PRIORITY, trap); return function () { eventBus.off(eventName, trap); }; } },{}],393:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.remove = remove; exports.add = add; exports.indexOf = indexOf; /** * Failsafe remove an element from a collection * * @param {Array} [collection] * @param {Object} [element] * * @return {Number} the previous index of the element */ function remove(collection, element) { if (!collection || !element) { return -1; } var idx = collection.indexOf(element); if (idx !== -1) { collection.splice(idx, 1); } return idx; } /** * Fail save add an element to the given connection, ensuring * it does not yet exist. * * @param {Array} collection * @param {Object} element * @param {Number} idx */ function add(collection, element, idx) { if (!collection || !element) { return; } if (typeof idx !== 'number') { idx = -1; } var currentIdx = collection.indexOf(element); if (currentIdx !== -1) { if (currentIdx === idx) { // nothing to do, position has not changed return; } else { if (idx !== -1) { // remove from current position collection.splice(currentIdx, 1); } else { // already exists in collection return; } } } if (idx !== -1) { // insert at specified position collection.splice(idx, 0, element); } else { // push to end collection.push(element); } } /** * Fail save get the index of an element in a collection. * * @param {Array} collection * @param {Object} element * * @return {Number} the index or -1 if collection or element do * not exist or the element is not contained. */ function indexOf(collection, element) { if (!collection || !element) { return -1; } return collection.indexOf(element); } },{}],394:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTopLevel = getTopLevel; var _minDash = require('min-dash'); function getTopLevel(elements) { var topLevel = {}, parents = [], result = [], clearedParents = []; (0, _minDash.forEach)(elements, function (element) { var parent = element.parent; if (!topLevel[parent.id]) { topLevel[parent.id] = []; } if (parents.indexOf(parent.id) === -1) { parents.push(parent.id); } topLevel[parent.id].push(element); }); (0, _minDash.forEach)(parents, function (parent) { (0, _minDash.forEach)(topLevel[parent], function (element) { if (topLevel[element.id]) { clearedParents.push(element.id); } }); }); (0, _minDash.forEach)(parents, function (parent) { var idx = clearedParents.indexOf(parent); if (idx === -1) { result = result.concat(topLevel[parent]); } }); return result; } },{"min-dash":505}],395:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.set = set; exports.unset = unset; exports.has = has; var _minDom = require('min-dom'); var CURSOR_CLS_PATTERN = /^djs-cursor-.*$/; function set(mode) { var classes = (0, _minDom.classes)(document.body); classes.removeMatching(CURSOR_CLS_PATTERN); if (mode) { classes.add('djs-cursor-' + mode); } } function unset() { set(null); } function has(mode) { var classes = (0, _minDom.classes)(document.body); return classes.has('djs-cursor-' + mode); } },{"min-dom":506}],396:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.add = add; exports.eachElement = eachElement; exports.selfAndChildren = selfAndChildren; exports.selfAndDirectChildren = selfAndDirectChildren; exports.selfAndAllChildren = selfAndAllChildren; exports.getClosure = getClosure; exports.getBBox = getBBox; exports.getEnclosedElements = getEnclosedElements; exports.getType = getType; var _minDash = require('min-dash'); /** * Adds an element to a collection and returns true if the * element was added. * * @param {Array} elements * @param {Object} e * @param {Boolean} unique */ function add(elements, e, unique) { var canAdd = !unique || elements.indexOf(e) === -1; if (canAdd) { elements.push(e); } return canAdd; } /** * Iterate over each element in a collection, calling the iterator function `fn` * with (element, index, recursionDepth). * * Recurse into all elements that are returned by `fn`. * * @param {Object|Array} elements * @param {Function} fn iterator function called with (element, index, recursionDepth) * @param {Number} [depth] maximum recursion depth */ function eachElement(elements, fn, depth) { depth = depth || 0; if (!(0, _minDash.isArray)(elements)) { elements = [elements]; } (0, _minDash.forEach)(elements, function (s, i) { var filter = fn(s, i, depth); if ((0, _minDash.isArray)(filter) && filter.length) { eachElement(filter, fn, depth + 1); } }); } /** * Collects self + child elements up to a given depth from a list of elements. * * @param {djs.model.Base|Array} elements the elements to select the children from * @param {Boolean} unique whether to return a unique result set (no duplicates) * @param {Number} maxDepth the depth to search through or -1 for infinite * * @return {Array} found elements */ function selfAndChildren(elements, unique, maxDepth) { var result = [], processedChildren = []; eachElement(elements, function (element, i, depth) { add(result, element, unique); var children = element.children; // max traversal depth not reached yet if (maxDepth === -1 || depth < maxDepth) { // children exist && children not yet processed if (children && add(processedChildren, children, unique)) { return children; } } }); return result; } /** * Return self + direct children for a number of elements * * @param {Array} elements to query * @param {Boolean} allowDuplicates to allow duplicates in the result set * * @return {Array} the collected elements */ function selfAndDirectChildren(elements, allowDuplicates) { return selfAndChildren(elements, !allowDuplicates, 1); } /** * Return self + ALL children for a number of elements * * @param {Array} elements to query * @param {Boolean} allowDuplicates to allow duplicates in the result set * * @return {Array} the collected elements */ function selfAndAllChildren(elements, allowDuplicates) { return selfAndChildren(elements, !allowDuplicates, -1); } /** * Gets the the closure for all selected elements, * their enclosed children and connections. * * @param {Array} elements * @param {Boolean} [isTopLevel=true] * @param {Object} [existingClosure] * * @return {Object} newClosure */ function getClosure(elements, isTopLevel, closure) { if ((0, _minDash.isUndefined)(isTopLevel)) { isTopLevel = true; } if ((0, _minDash.isObject)(isTopLevel)) { closure = isTopLevel; isTopLevel = true; } closure = closure || {}; var allShapes = copyObject(closure.allShapes), allConnections = copyObject(closure.allConnections), enclosedElements = copyObject(closure.enclosedElements), enclosedConnections = copyObject(closure.enclosedConnections); var topLevel = copyObject(closure.topLevel, isTopLevel && (0, _minDash.groupBy)(elements, function (e) { return e.id; })); function handleConnection(c) { if (topLevel[c.source.id] && topLevel[c.target.id]) { topLevel[c.id] = [c]; } // not enclosed as a child, but maybe logically // (connecting two moved elements?) if (allShapes[c.source.id] && allShapes[c.target.id]) { enclosedConnections[c.id] = enclosedElements[c.id] = c; } allConnections[c.id] = c; } function handleElement(element) { enclosedElements[element.id] = element; if (element.waypoints) { // remember connection enclosedConnections[element.id] = allConnections[element.id] = element; } else { // remember shape allShapes[element.id] = element; // remember all connections (0, _minDash.forEach)(element.incoming, handleConnection); (0, _minDash.forEach)(element.outgoing, handleConnection); // recurse into children return element.children; } } eachElement(elements, handleElement); return { allShapes: allShapes, allConnections: allConnections, topLevel: topLevel, enclosedConnections: enclosedConnections, enclosedElements: enclosedElements }; } /** * Returns the surrounding bbox for all elements in * the array or the element primitive. * * @param {Array|djs.model.Shape} elements * @param {Boolean} stopRecursion */ function getBBox(elements, stopRecursion) { stopRecursion = !!stopRecursion; if (!(0, _minDash.isArray)(elements)) { elements = [elements]; } var minX, minY, maxX, maxY; (0, _minDash.forEach)(elements, function (element) { // If element is a connection the bbox must be computed first var bbox = element; if (element.waypoints && !stopRecursion) { bbox = getBBox(element.waypoints, true); } var x = bbox.x, y = bbox.y, height = bbox.height || 0, width = bbox.width || 0; if (x < minX || minX === undefined) { minX = x; } if (y < minY || minY === undefined) { minY = y; } if (x + width > maxX || maxX === undefined) { maxX = x + width; } if (y + height > maxY || maxY === undefined) { maxY = y + height; } }); return { x: minX, y: minY, height: maxY - minY, width: maxX - minX }; } /** * Returns all elements that are enclosed from the bounding box. * * * If bbox.(width|height) is not specified the method returns * all elements with element.x/y > bbox.x/y * * If only bbox.x or bbox.y is specified, method return all elements with * e.x > bbox.x or e.y > bbox.y * * @param {Array} elements List of Elements to search through * @param {djs.model.Shape} bbox the enclosing bbox. * * @return {Array} enclosed elements */ function getEnclosedElements(elements, bbox) { var filteredElements = {}; (0, _minDash.forEach)(elements, function (element) { var e = element; if (e.waypoints) { e = getBBox(e); } if (!(0, _minDash.isNumber)(bbox.y) && e.x > bbox.x) { filteredElements[element.id] = element; } if (!(0, _minDash.isNumber)(bbox.x) && e.y > bbox.y) { filteredElements[element.id] = element; } if (e.x > bbox.x && e.y > bbox.y) { if ((0, _minDash.isNumber)(bbox.width) && (0, _minDash.isNumber)(bbox.height) && e.width + e.x < bbox.width + bbox.x && e.height + e.y < bbox.height + bbox.y) { filteredElements[element.id] = element; } else if (!(0, _minDash.isNumber)(bbox.width) || !(0, _minDash.isNumber)(bbox.height)) { filteredElements[element.id] = element; } } }); return filteredElements; } function getType(element) { if ('waypoints' in element) { return 'connection'; } if ('x' in element) { return 'shape'; } return 'root'; } // helpers /////////////////////////////// function copyObject(src1, src2) { return (0, _minDash.assign)({}, src1 || {}, src2 || {}); } },{"min-dash":505}],397:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getOriginal = getOriginal; exports.stopPropagation = stopPropagation; exports.toPoint = toPoint; function __stopPropagation(event) { if (!event || typeof event.stopPropagation !== 'function') { return; } event.stopPropagation(); } function getOriginal(event) { return event.originalEvent || event.srcEvent; } function stopPropagation(event, immediate) { __stopPropagation(event, immediate); __stopPropagation(getOriginal(event), immediate); } function toPoint(event) { if (event.pointers && event.pointers.length) { event = event.pointers[0]; } if (event.touches && event.touches.length) { event = event.touches[0]; } return event ? { x: event.clientX, y: event.clientY } : null; } },{}],398:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.pointDistance = pointDistance; exports.pointsOnLine = pointsOnLine; exports.pointsAligned = pointsAligned; exports.pointInRect = pointInRect; exports.getMidPoint = getMidPoint; /** * Computes the distance between two points * * @param {Point} p * @param {Point} q * * @return {Number} distance */ function pointDistance(a, b) { if (!a || !b) { return -1; } return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2)); } /** * Returns true if the point r is on the line between p and q * * @param {Point} p * @param {Point} q * @param {Point} r * @param {Number} [accuracy=5] accuracy for points on line check (lower is better) * * @return {Boolean} */ function pointsOnLine(p, q, r, accuracy) { if (typeof accuracy === 'undefined') { accuracy = 5; } if (!p || !q || !r) { return false; } var val = (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x), dist = pointDistance(p, q); // @see http://stackoverflow.com/a/907491/412190 return Math.abs(val / dist) <= accuracy; } var ALIGNED_THRESHOLD = 2; /** * Returns whether two points are in a horizontal or vertical line. * * @param {Point} a * @param {Point} b * * @return {String|Boolean} returns false if the points are not * aligned or 'h|v' if they are aligned * horizontally / vertically. */ function pointsAligned(a, b) { if (Math.abs(a.x - b.x) <= ALIGNED_THRESHOLD) { return 'h'; } if (Math.abs(a.y - b.y) <= ALIGNED_THRESHOLD) { return 'v'; } return false; } /** * Returns true if the point p is inside the rectangle rect * * @param {Point} p * @param {Rect} rect * @param {Number} tolerance * * @return {Boolean} */ function pointInRect(p, rect, tolerance) { tolerance = tolerance || 0; return p.x > rect.x - tolerance && p.y > rect.y - tolerance && p.x < rect.x + rect.width + tolerance && p.y < rect.y + rect.height + tolerance; } /** * Returns a point in the middle of points p and q * * @param {Point} p * @param {Point} q * * @return {Point} middle point */ function getMidPoint(p, q) { return { x: Math.round(p.x + (q.x - p.x) / 2.0), y: Math.round(p.y + (q.y - p.y) / 2.0) }; } },{}],399:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getVisual = getVisual; exports.getChildren = getChildren; var _minDom = require('min-dom'); /** * SVGs for elements are generated by the {@link GraphicsFactory}. * * This utility gives quick access to the important semantic * parts of an element. */ /** * Returns the visual part of a diagram element * * @param {Snap} gfx * * @return {Snap} */ function getVisual(gfx) { return (0, _minDom.query)('.djs-visual', gfx); } /** * Returns the children for a given diagram element. * * @param {Snap} gfx * @return {Snap} */ function getChildren(gfx) { return gfx.parentNode.childNodes[1]; } },{"min-dom":506}],400:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = IdGenerator; /** * Util that provides unique IDs. * * @class djs.util.IdGenerator * @constructor * @memberOf djs.util * * The ids can be customized via a given prefix and contain a random value to avoid collisions. * * @param {String} prefix a prefix to prepend to generated ids (for better readability) */ function IdGenerator(prefix) { this._counter = 0; this._prefix = (prefix ? prefix + '-' : '') + Math.floor(Math.random() * 1000000000) + '-'; } /** * Returns a next unique ID. * * @method djs.util.IdGenerator#next * * @returns {String} the id */ IdGenerator.prototype.next = function () { return this._prefix + ++this._counter; }; },{}],401:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getApproxIntersection = getApproxIntersection; var _Geometry = require('./Geometry'); var _pathIntersection = require('path-intersection'); var _pathIntersection2 = _interopRequireDefault(_pathIntersection); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var round = Math.round, max = Math.max; function circlePath(center, r) { var x = center.x, y = center.y; return [['M', x, y], ['m', 0, -r], ['a', r, r, 0, 1, 1, 0, 2 * r], ['a', r, r, 0, 1, 1, 0, -2 * r], ['z']]; } function linePath(points) { var segments = []; points.forEach(function (p, idx) { segments.push([idx === 0 ? 'M' : 'L', p.x, p.y]); }); return segments; } var INTERSECTION_THRESHOLD = 10; function getBendpointIntersection(waypoints, reference) { var i, w; for (i = 0; w = waypoints[i]; i++) { if ((0, _Geometry.pointDistance)(w, reference) <= INTERSECTION_THRESHOLD) { return { point: waypoints[i], bendpoint: true, index: i }; } } return null; } function getPathIntersection(waypoints, reference) { var intersections = (0, _pathIntersection2.default)(circlePath(reference, INTERSECTION_THRESHOLD), linePath(waypoints)); var a = intersections[0], b = intersections[intersections.length - 1], idx; if (!a) { // no intersection return null; } if (a !== b) { if (a.segment2 !== b.segment2) { // we use the bendpoint in between both segments // as the intersection point idx = max(a.segment2, b.segment2) - 1; return { point: waypoints[idx], bendpoint: true, index: idx }; } return { point: { x: round(a.x + b.x) / 2, y: round(a.y + b.y) / 2 }, index: a.segment2 }; } return { point: { x: round(a.x), y: round(a.y) }, index: a.segment2 }; } /** * Returns the closest point on the connection towards a given reference point. * * @param {Array} waypoints * @param {Point} reference * * @return {Object} intersection data (segment, point) */ function getApproxIntersection(waypoints, reference) { return getBendpointIntersection(waypoints, reference) || getPathIntersection(waypoints, reference); } },{"./Geometry":398,"path-intersection":523}],402:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.log10 = log10; var _PositionUtil = require('./PositionUtil'); Object.defineProperty(exports, 'substract', { enumerable: true, get: function get() { return _PositionUtil.delta; } }); /** * Get the logarithm of x with base 10 * @param {Integer} value */ function log10(x) { return Math.log(x) / Math.log(10); } },{"./PositionUtil":405}],403:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.isMac = undefined; var _Platform = require('./Platform'); Object.defineProperty(exports, 'isMac', { enumerable: true, get: function get() { return _Platform.isMac; } }); exports.isPrimaryButton = isPrimaryButton; exports.hasPrimaryModifier = hasPrimaryModifier; exports.hasSecondaryModifier = hasSecondaryModifier; var _Event = require('./Event'); function isPrimaryButton(event) { // button === 0 -> left áka primary mouse button return !((0, _Event.getOriginal)(event) || event).button; } function hasPrimaryModifier(event) { var originalEvent = (0, _Event.getOriginal)(event) || event; if (!isPrimaryButton(event)) { return false; } // Use alt as primary modifier key for mac OS if ((0, _Platform.isMac)()) { return originalEvent.metaKey; } else { return originalEvent.ctrlKey; } } function hasSecondaryModifier(event) { var originalEvent = (0, _Event.getOriginal)(event) || event; return isPrimaryButton(event) && originalEvent.shiftKey; } },{"./Event":397,"./Platform":404}],404:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isMac = isMac; function isMac() { return (/mac/i.test(navigator.platform) ); } },{}],405:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.center = center; exports.delta = delta; function center(bounds) { return { x: bounds.x + bounds.width / 2, y: bounds.y + bounds.height / 2 }; } function delta(a, b) { return { x: a.x - b.x, y: a.y - b.y }; } },{}],406:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.saveClear = saveClear; /** * Remove from the beginning of a collection until it is empty. * * This is a null-safe operation that ensures elements * are being removed from the given collection until the * collection is empty. * * The implementation deals with the fact that a remove operation * may touch, i.e. remove multiple elements in the collection * at a time. * * @param {Array} [collection] * @param {Function} removeFn * * @return {Array} the cleared collection */ function saveClear(collection, removeFn) { if (typeof removeFn !== 'function') { throw new Error('removeFn iterator must be a function'); } if (!collection) { return; } var e; while (e = collection[0]) { removeFn(e); } return collection; } },{}],407:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.componentsToPath = componentsToPath; exports.toSVGPoints = toSVGPoints; exports.createLine = createLine; exports.updateLine = updateLine; var _tinySvg = require('tiny-svg'); function componentsToPath(elements) { return elements.join(',').replace(/,?([A-z]),?/g, '$1'); } function toSVGPoints(points) { var result = ''; for (var i = 0, p; p = points[i]; i++) { result += p.x + ',' + p.y + ' '; } return result; } function createLine(points, attrs) { var line = (0, _tinySvg.create)('polyline'); (0, _tinySvg.attr)(line, { points: toSVGPoints(points) }); if (attrs) { (0, _tinySvg.attr)(line, attrs); } return line; } function updateLine(gfx, points) { (0, _tinySvg.attr)(gfx, { points: toSVGPoints(points) }); return gfx; } },{"tiny-svg":535}],408:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.transform = transform; exports.translate = translate; exports.rotate = rotate; exports.scale = scale; var _tinySvg = require('tiny-svg'); /** * @param {} element * @param {Number} x * @param {Number} y * @param {Number} angle * @param {Number} amount */ function transform(gfx, x, y, angle, amount) { var translate = (0, _tinySvg.createTransform)(); translate.setTranslate(x, y); var rotate = (0, _tinySvg.createTransform)(); rotate.setRotate(angle, 0, 0); var scale = (0, _tinySvg.createTransform)(); scale.setScale(amount || 1, amount || 1); (0, _tinySvg.transform)(gfx, [translate, rotate, scale]); } /** * @param {SVGElement} element * @param {Number} x * @param {Number} y */ function translate(gfx, x, y) { var translate = (0, _tinySvg.createTransform)(); translate.setTranslate(x, y); (0, _tinySvg.transform)(gfx, translate); } /** * @param {SVGElement} element * @param {Number} angle */ function rotate(gfx, angle) { var rotate = (0, _tinySvg.createTransform)(); rotate.setRotate(angle, 0, 0); (0, _tinySvg.transform)(gfx, rotate); } /** * @param {SVGElement} element * @param {Number} amount */ function scale(gfx, amount) { var scale = (0, _tinySvg.createTransform)(); scale.setScale(amount, amount); (0, _tinySvg.transform)(gfx, scale); } },{"tiny-svg":535}],409:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Text; var _minDash = require('min-dash'); var _tinySvg = require('tiny-svg'); var DEFAULT_BOX_PADDING = 0; var DEFAULT_LABEL_SIZE = { width: 150, height: 50 }; function parseAlign(align) { var parts = align.split('-'); return { horizontal: parts[0] || 'center', vertical: parts[1] || 'top' }; } function parsePadding(padding) { if ((0, _minDash.isObject)(padding)) { return (0, _minDash.assign)({ top: 0, left: 0, right: 0, bottom: 0 }, padding); } else { return { top: padding, left: padding, right: padding, bottom: padding }; } } function getTextBBox(text, fakeText) { fakeText.textContent = text; var textBBox; try { var bbox, emptyLine = text === ''; // add dummy text, when line is empty to // determine correct height fakeText.textContent = emptyLine ? 'dummy' : text; textBBox = fakeText.getBBox(); // take text rendering related horizontal // padding into account bbox = { width: textBBox.width + textBBox.x * 2, height: textBBox.height }; if (emptyLine) { // correct width bbox.width = 0; } return bbox; } catch (e) { return { width: 0, height: 0 }; } } /** * Layout the next line and return the layouted element. * * Alters the lines passed. * * @param {Array} lines * @return {Object} the line descriptor, an object { width, height, text } */ function layoutNext(lines, maxWidth, fakeText) { var originalLine = lines.shift(), fitLine = originalLine; var textBBox; for (;;) { textBBox = getTextBBox(fitLine, fakeText); textBBox.width = fitLine ? textBBox.width : 0; // try to fit if (fitLine === ' ' || fitLine === '' || textBBox.width < Math.round(maxWidth) || fitLine.length < 2) { return fit(lines, fitLine, originalLine, textBBox); } fitLine = shortenLine(fitLine, textBBox.width, maxWidth); } } function fit(lines, fitLine, originalLine, textBBox) { if (fitLine.length < originalLine.length) { var remainder = originalLine.slice(fitLine.length).trim(); lines.unshift(remainder); } return { width: textBBox.width, height: textBBox.height, text: fitLine }; } /** * Shortens a line based on spacing and hyphens. * Returns the shortened result on success. * * @param {String} line * @param {Number} maxLength the maximum characters of the string * @return {String} the shortened string */ function semanticShorten(line, maxLength) { var parts = line.split(/(\s|-)/g), part, shortenedParts = [], length = 0; // try to shorten via spaces + hyphens if (parts.length > 1) { while (part = parts.shift()) { if (part.length + length < maxLength) { shortenedParts.push(part); length += part.length; } else { // remove previous part, too if hyphen does not fit anymore if (part === '-') { shortenedParts.pop(); } break; } } } return shortenedParts.join(''); } function shortenLine(line, width, maxWidth) { var length = Math.max(line.length * (maxWidth / width), 1); // try to shorten semantically (i.e. based on spaces and hyphens) var shortenedLine = semanticShorten(line, length); if (!shortenedLine) { // force shorten by cutting the long word shortenedLine = line.slice(0, Math.max(Math.round(length - 1), 1)); } return shortenedLine; } function getHelperSvg() { var helperSvg = document.getElementById('helper-svg'); if (!helperSvg) { helperSvg = (0, _tinySvg.create)('svg'); (0, _tinySvg.attr)(helperSvg, { id: 'helper-svg', width: 0, height: 0, style: 'visibility: hidden; position: fixed' }); document.body.appendChild(helperSvg); } return helperSvg; } /** * Creates a new label utility * * @param {Object} config * @param {Dimensions} config.size * @param {Number} config.padding * @param {Object} config.style * @param {String} config.align */ function Text(config) { this._config = (0, _minDash.assign)({}, { size: DEFAULT_LABEL_SIZE, padding: DEFAULT_BOX_PADDING, style: {}, align: 'center-top' }, config || {}); } /** * Returns the layouted text as an SVG element. * * @param {String} text * @param {Object} options * * @return {SVGElement} */ Text.prototype.createText = function (text, options) { return this.layoutText(text, options).element; }; /** * Returns a labels layouted dimensions. * * @param {String} text to layout * @param {Object} options * * @return {Dimensions} */ Text.prototype.getDimensions = function (text, options) { return this.layoutText(text, options).dimensions; }; /** * Creates and returns a label and its bounding box. * * @method Text#createText * * @param {String} text the text to render on the label * @param {Object} options * @param {String} options.align how to align in the bounding box. * Any of { 'center-middle', 'center-top' }, * defaults to 'center-top'. * @param {String} options.style style to be applied to the text * @param {boolean} options.fitBox indicates if box will be recalculated to * fit text * * @return {Object} { element, dimensions } */ Text.prototype.layoutText = function (text, options) { var box = (0, _minDash.assign)({}, this._config.size, options.box), style = (0, _minDash.assign)({}, this._config.style, options.style), align = parseAlign(options.align || this._config.align), padding = parsePadding(options.padding !== undefined ? options.padding : this._config.padding), fitBox = options.fitBox || false; var lineHeight = getLineHeight(style); var lines = text.split(/\r?\n/g), layouted = []; var maxWidth = box.width - padding.left - padding.right; // ensure correct rendering by attaching helper text node to invisible SVG var helperText = (0, _tinySvg.create)('text'); (0, _tinySvg.attr)(helperText, { x: 0, y: 0 }); (0, _tinySvg.attr)(helperText, style); var helperSvg = getHelperSvg(); (0, _tinySvg.append)(helperSvg, helperText); while (lines.length) { layouted.push(layoutNext(lines, maxWidth, helperText)); } if (align.vertical === 'middle') { padding.top = padding.bottom = 0; } var totalHeight = (0, _minDash.reduce)(layouted, function (sum, line, idx) { return sum + (lineHeight || line.height); }, 0) + padding.top + padding.bottom; var maxLineWidth = (0, _minDash.reduce)(layouted, function (sum, line, idx) { return line.width > sum ? line.width : sum; }, 0); // the y position of the next line var y = padding.top; if (align.vertical === 'middle') { y += (box.height - totalHeight) / 2; } // magic number initial offset y -= (lineHeight || layouted[0].height) / 4; var textElement = (0, _tinySvg.create)('text'); (0, _tinySvg.attr)(textElement, style); // layout each line taking into account that parent // shape might resize to fit text size (0, _minDash.forEach)(layouted, function (line) { var x; y += lineHeight || line.height; switch (align.horizontal) { case 'left': x = padding.left; break; case 'right': x = (fitBox ? maxLineWidth : maxWidth) - padding.right - line.width; break; default: // aka center x = Math.max(((fitBox ? maxLineWidth : maxWidth) - line.width) / 2 + padding.left, 0); } var tspan = (0, _tinySvg.create)('tspan'); (0, _tinySvg.attr)(tspan, { x: x, y: y }); tspan.textContent = line.text; (0, _tinySvg.append)(textElement, tspan); }); (0, _tinySvg.remove)(helperText); var dimensions = { width: maxLineWidth, height: totalHeight }; return { dimensions: dimensions, element: textElement }; }; function getLineHeight(style) { if ('fontSize' in style && 'lineHeight' in style) { return style.lineHeight * parseInt(style.fontSize, 10); } } },{"min-dash":505,"tiny-svg":535}],410:[function(require,module,exports){ 'use strict'; var _typeof2 = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; Object.defineProperty(exports, '__esModule', { value: true }); var CLASS_PATTERN = /^class /; function isClass(fn) { return CLASS_PATTERN.test(fn.toString()); } function isArray(obj) { return Object.prototype.toString.call(obj) === '[object Array]'; } function annotate() { var args = Array.prototype.slice.call(arguments); if (args.length === 1 && isArray(args[0])) { args = args[0]; } var fn = args.pop(); fn.$inject = args; return fn; } // Current limitations: // - can't put into "function arg" comments // function /* (no parenthesis like this) */ (){} // function abc( /* xx (no parenthesis like this) */ a, b) {} // // Just put the comment before function or inside: // /* (((this is fine))) */ function(a, b) {} // function abc(a) { /* (((this is fine))) */} // // - can't reliably auto-annotate constructor; we'll match the // first constructor(...) pattern found which may be the one // of a nested class, too. var CONSTRUCTOR_ARGS = /constructor\s*[^(]*\(\s*([^)]*)\)/m; var FN_ARGS = /^function\s*[^(]*\(\s*([^)]*)\)/m; var FN_ARG = /\/\*([^*]*)\*\//m; function parse(fn) { if (typeof fn !== 'function') { throw new Error('Cannot annotate "' + fn + '". Expected a function!'); } var match = fn.toString().match(isClass(fn) ? CONSTRUCTOR_ARGS : FN_ARGS); // may parse class without constructor if (!match) { return []; } return match[1] && match[1].split(',').map(function (arg) { match = arg.match(FN_ARG); return match ? match[1].trim() : arg.trim(); }) || []; } function Module() { var providers = []; this.factory = function (name, factory) { providers.push([name, 'factory', factory]); return this; }; this.value = function (name, value) { providers.push([name, 'value', value]); return this; }; this.type = function (name, type) { providers.push([name, 'type', type]); return this; }; this.forEach = function (iterator) { providers.forEach(iterator); }; } var _typeof = typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol" ? function (obj) { return typeof obj === 'undefined' ? 'undefined' : _typeof2(obj); } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj === 'undefined' ? 'undefined' : _typeof2(obj); }; function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; }return arr2; } else { return Array.from(arr); } } function Injector(modules, parent) { parent = parent || { get: function get(name, strict) { currentlyResolving.push(name); if (strict === false) { return null; } else { throw error('No provider for "' + name + '"!'); } } }; var currentlyResolving = []; var providers = this._providers = Object.create(parent._providers || null); var instances = this._instances = Object.create(null); var self = instances.injector = this; var error = function error(msg) { var stack = currentlyResolving.join(' -> '); currentlyResolving.length = 0; return new Error(stack ? msg + ' (Resolving: ' + stack + ')' : msg); }; /** * Return a named service. * * @param {String} name * @param {Boolean} [strict=true] if false, resolve missing services to null * * @return {Object} */ var get = function get(name, strict) { if (!providers[name] && name.indexOf('.') !== -1) { var parts = name.split('.'); var pivot = get(parts.shift()); while (parts.length) { pivot = pivot[parts.shift()]; } return pivot; } if (hasProp(instances, name)) { return instances[name]; } if (hasProp(providers, name)) { if (currentlyResolving.indexOf(name) !== -1) { currentlyResolving.push(name); throw error('Cannot resolve circular dependency!'); } currentlyResolving.push(name); instances[name] = providers[name][0](providers[name][1]); currentlyResolving.pop(); return instances[name]; } return parent.get(name, strict); }; var fnDef = function fnDef(fn) { var locals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (typeof fn !== 'function') { if (isArray(fn)) { fn = annotate(fn.slice()); } else { throw new Error('Cannot invoke "' + fn + '". Expected a function!'); } } var inject = fn.$inject || parse(fn); var dependencies = inject.map(function (dep) { if (hasProp(locals, dep)) { return locals[dep]; } else { return get(dep); } }); return { fn: fn, dependencies: dependencies }; }; var instantiate = function instantiate(Type) { var _fnDef = fnDef(Type), dependencies = _fnDef.dependencies, fn = _fnDef.fn; return new (Function.prototype.bind.apply(fn, [null].concat(_toConsumableArray(dependencies))))(); }; var invoke = function invoke(func, context, locals) { var _fnDef2 = fnDef(func, locals), dependencies = _fnDef2.dependencies, fn = _fnDef2.fn; return fn.call.apply(fn, [context].concat(_toConsumableArray(dependencies))); }; var createPrivateInjectorFactory = function createPrivateInjectorFactory(privateChildInjector) { return annotate(function (key) { return privateChildInjector.get(key); }); }; var createChild = function createChild(modules, forceNewInstances) { if (forceNewInstances && forceNewInstances.length) { var fromParentModule = Object.create(null); var matchedScopes = Object.create(null); var privateInjectorsCache = []; var privateChildInjectors = []; var privateChildFactories = []; var provider; var cacheIdx; var privateChildInjector; var privateChildInjectorFactory; for (var name in providers) { provider = providers[name]; if (forceNewInstances.indexOf(name) !== -1) { if (provider[2] === 'private') { cacheIdx = privateInjectorsCache.indexOf(provider[3]); if (cacheIdx === -1) { privateChildInjector = provider[3].createChild([], forceNewInstances); privateChildInjectorFactory = createPrivateInjectorFactory(privateChildInjector); privateInjectorsCache.push(provider[3]); privateChildInjectors.push(privateChildInjector); privateChildFactories.push(privateChildInjectorFactory); fromParentModule[name] = [privateChildInjectorFactory, name, 'private', privateChildInjector]; } else { fromParentModule[name] = [privateChildFactories[cacheIdx], name, 'private', privateChildInjectors[cacheIdx]]; } } else { fromParentModule[name] = [provider[2], provider[1]]; } matchedScopes[name] = true; } if ((provider[2] === 'factory' || provider[2] === 'type') && provider[1].$scope) { /* jshint -W083 */ forceNewInstances.forEach(function (scope) { if (provider[1].$scope.indexOf(scope) !== -1) { fromParentModule[name] = [provider[2], provider[1]]; matchedScopes[scope] = true; } }); } } forceNewInstances.forEach(function (scope) { if (!matchedScopes[scope]) { throw new Error('No provider for "' + scope + '". Cannot use provider from the parent!'); } }); modules.unshift(fromParentModule); } return new Injector(modules, self); }; var factoryMap = { factory: invoke, type: instantiate, value: function value(_value) { return _value; } }; modules.forEach(function (module) { function arrayUnwrap(type, value) { if (type !== 'value' && isArray(value)) { value = annotate(value.slice()); } return value; } // TODO(vojta): handle wrong inputs (modules) if (module instanceof Module) { module.forEach(function (provider) { var name = provider[0]; var type = provider[1]; var value = provider[2]; providers[name] = [factoryMap[type], arrayUnwrap(type, value), type]; }); } else if ((typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') { if (module.__exports__) { var clonedModule = Object.keys(module).reduce(function (m, key) { if (key.substring(0, 2) !== '__') { m[key] = module[key]; } return m; }, Object.create(null)); var privateInjector = new Injector((module.__modules__ || []).concat([clonedModule]), self); var getFromPrivateInjector = annotate(function (key) { return privateInjector.get(key); }); module.__exports__.forEach(function (key) { providers[key] = [getFromPrivateInjector, key, 'private', privateInjector]; }); } else { Object.keys(module).forEach(function (name) { if (module[name][2] === 'private') { providers[name] = module[name]; return; } var type = module[name][0]; var value = module[name][1]; providers[name] = [factoryMap[type], arrayUnwrap(type, value), type]; }); } } }); // public API this.get = get; this.invoke = invoke; this.instantiate = instantiate; this.createChild = createChild; } // helpers ///////////////// function hasProp(obj, prop) { return Object.hasOwnProperty.call(obj, prop); } exports.annotate = annotate; exports.Module = Module; exports.Injector = Injector; },{}],411:[function(require,module,exports){ 'use strict'; /** * Expose `parse`. */ module.exports = parse; /** * Tests for browser support. */ var innerHTMLBug = false; var bugTestDiv; if (typeof document !== 'undefined') { bugTestDiv = document.createElement('div'); // Setup bugTestDiv.innerHTML = '
a'; // Make sure that link elements get serialized correctly by innerHTML // This requires a wrapper element in IE innerHTMLBug = !bugTestDiv.getElementsByTagName('link').length; bugTestDiv = undefined; } /** * Wrap map from jquery. */ var map = { legend: [1, '
', '
'], tr: [2, '', '
'], col: [2, '', '
'], // for script/link/style tags to work in IE6-8, you have to wrap // in a div with a non-whitespace character in front, ha! _default: innerHTMLBug ? [1, 'X
', '
'] : [0, '', ''] }; map.td = map.th = [3, '', '
']; map.option = map.optgroup = [1, '']; map.thead = map.tbody = map.colgroup = map.caption = map.tfoot = [1, '', '
']; map.polyline = map.ellipse = map.polygon = map.circle = map.text = map.line = map.path = map.rect = map.g = [1, '', '']; /** * Parse `html` and return a DOM Node instance, which could be a TextNode, * HTML DOM Node of some kind (
for example), or a DocumentFragment * instance, depending on the contents of the `html` string. * * @param {String} html - HTML string to "domify" * @param {Document} doc - The `document` instance to create the Node for * @return {DOMNode} the TextNode, DOM Node, or DocumentFragment instance * @api private */ function parse(html, doc) { if ('string' != typeof html) throw new TypeError('String expected'); // default to the global `document` object if (!doc) doc = document; // tag name var m = /<([\w:]+)/.exec(html); if (!m) return doc.createTextNode(html); html = html.replace(/^\s+|\s+$/g, ''); // Remove leading/trailing whitespace var tag = m[1]; // body support if (tag == 'body') { var el = doc.createElement('html'); el.innerHTML = html; return el.removeChild(el.lastChild); } // wrap map var wrap = map[tag] || map._default; var depth = wrap[0]; var prefix = wrap[1]; var suffix = wrap[2]; var el = doc.createElement('div'); el.innerHTML = prefix + html + suffix; while (depth--) { el = el.lastChild; } // one element if (el.firstChild == el.lastChild) { return el.removeChild(el.firstChild); } // several elements var fragment = doc.createDocumentFragment(); while (el.firstChild) { fragment.appendChild(el.removeChild(el.firstChild)); } return fragment; } },{}],412:[function(require,module,exports){ 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /*! Hammer.JS - v2.0.7 - 2016-04-22 * http://hammerjs.github.io/ * * Copyright (c) 2016 Jorik Tangelder; * Licensed under the MIT license */ (function (window, document, exportName, undefined) { 'use strict'; var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o']; var TEST_ELEMENT = document.createElement('div'); var TYPE_FUNCTION = 'function'; var round = Math.round; var abs = Math.abs; var now = Date.now; /** * set a timeout with a given scope * @param {Function} fn * @param {Number} timeout * @param {Object} context * @returns {number} */ function setTimeoutContext(fn, timeout, context) { return setTimeout(bindFn(fn, context), timeout); } /** * if the argument is an array, we want to execute the fn on each entry * if it aint an array we don't want to do a thing. * this is used by all the methods that accept a single and array argument. * @param {*|Array} arg * @param {String} fn * @param {Object} [context] * @returns {Boolean} */ function invokeArrayArg(arg, fn, context) { if (Array.isArray(arg)) { each(arg, context[fn], context); return true; } return false; } /** * walk objects and arrays * @param {Object} obj * @param {Function} iterator * @param {Object} context */ function each(obj, iterator, context) { var i; if (!obj) { return; } if (obj.forEach) { obj.forEach(iterator, context); } else if (obj.length !== undefined) { i = 0; while (i < obj.length) { iterator.call(context, obj[i], i, obj); i++; } } else { for (i in obj) { obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj); } } } /** * wrap a method with a deprecation warning and stack trace * @param {Function} method * @param {String} name * @param {String} message * @returns {Function} A new function wrapping the supplied method. */ function deprecate(method, name, message) { var deprecationMessage = 'DEPRECATED METHOD: ' + name + '\n' + message + ' AT \n'; return function () { var e = new Error('get-stack-trace'); var stack = e && e.stack ? e.stack.replace(/^[^\(]+?[\n$]/gm, '').replace(/^\s+at\s+/gm, '').replace(/^Object.\s*\(/gm, '{anonymous}()@') : 'Unknown Stack Trace'; var log = window.console && (window.console.warn || window.console.log); if (log) { log.call(window.console, deprecationMessage, stack); } return method.apply(this, arguments); }; } /** * extend object. * means that properties in dest will be overwritten by the ones in src. * @param {Object} target * @param {...Object} objects_to_assign * @returns {Object} target */ var assign; if (typeof Object.assign !== 'function') { assign = function assign(target) { if (target === undefined || target === null) { throw new TypeError('Cannot convert undefined or null to object'); } var output = Object(target); for (var index = 1; index < arguments.length; index++) { var source = arguments[index]; if (source !== undefined && source !== null) { for (var nextKey in source) { if (source.hasOwnProperty(nextKey)) { output[nextKey] = source[nextKey]; } } } } return output; }; } else { assign = Object.assign; } /** * extend object. * means that properties in dest will be overwritten by the ones in src. * @param {Object} dest * @param {Object} src * @param {Boolean} [merge=false] * @returns {Object} dest */ var extend = deprecate(function extend(dest, src, merge) { var keys = Object.keys(src); var i = 0; while (i < keys.length) { if (!merge || merge && dest[keys[i]] === undefined) { dest[keys[i]] = src[keys[i]]; } i++; } return dest; }, 'extend', 'Use `assign`.'); /** * merge the values from src in the dest. * means that properties that exist in dest will not be overwritten by src * @param {Object} dest * @param {Object} src * @returns {Object} dest */ var merge = deprecate(function merge(dest, src) { return extend(dest, src, true); }, 'merge', 'Use `assign`.'); /** * simple class inheritance * @param {Function} child * @param {Function} base * @param {Object} [properties] */ function inherit(child, base, properties) { var baseP = base.prototype, childP; childP = child.prototype = Object.create(baseP); childP.constructor = child; childP._super = baseP; if (properties) { assign(childP, properties); } } /** * simple function bind * @param {Function} fn * @param {Object} context * @returns {Function} */ function bindFn(fn, context) { return function boundFn() { return fn.apply(context, arguments); }; } /** * let a boolean value also be a function that must return a boolean * this first item in args will be used as the context * @param {Boolean|Function} val * @param {Array} [args] * @returns {Boolean} */ function boolOrFn(val, args) { if ((typeof val === 'undefined' ? 'undefined' : _typeof(val)) == TYPE_FUNCTION) { return val.apply(args ? args[0] || undefined : undefined, args); } return val; } /** * use the val2 when val1 is undefined * @param {*} val1 * @param {*} val2 * @returns {*} */ function ifUndefined(val1, val2) { return val1 === undefined ? val2 : val1; } /** * addEventListener with multiple events at once * @param {EventTarget} target * @param {String} types * @param {Function} handler */ function addEventListeners(target, types, handler) { each(splitStr(types), function (type) { target.addEventListener(type, handler, false); }); } /** * removeEventListener with multiple events at once * @param {EventTarget} target * @param {String} types * @param {Function} handler */ function removeEventListeners(target, types, handler) { each(splitStr(types), function (type) { target.removeEventListener(type, handler, false); }); } /** * find if a node is in the given parent * @method hasParent * @param {HTMLElement} node * @param {HTMLElement} parent * @return {Boolean} found */ function hasParent(node, parent) { while (node) { if (node == parent) { return true; } node = node.parentNode; } return false; } /** * small indexOf wrapper * @param {String} str * @param {String} find * @returns {Boolean} found */ function inStr(str, find) { return str.indexOf(find) > -1; } /** * split string on whitespace * @param {String} str * @returns {Array} words */ function splitStr(str) { return str.trim().split(/\s+/g); } /** * find if a array contains the object using indexOf or a simple polyFill * @param {Array} src * @param {String} find * @param {String} [findByKey] * @return {Boolean|Number} false when not found, or the index */ function inArray(src, find, findByKey) { if (src.indexOf && !findByKey) { return src.indexOf(find); } else { var i = 0; while (i < src.length) { if (findByKey && src[i][findByKey] == find || !findByKey && src[i] === find) { return i; } i++; } return -1; } } /** * convert array-like objects to real arrays * @param {Object} obj * @returns {Array} */ function toArray(obj) { return Array.prototype.slice.call(obj, 0); } /** * unique array with objects based on a key (like 'id') or just by the array's value * @param {Array} src [{id:1},{id:2},{id:1}] * @param {String} [key] * @param {Boolean} [sort=False] * @returns {Array} [{id:1},{id:2}] */ function uniqueArray(src, key, sort) { var results = []; var values = []; var i = 0; while (i < src.length) { var val = key ? src[i][key] : src[i]; if (inArray(values, val) < 0) { results.push(src[i]); } values[i] = val; i++; } if (sort) { if (!key) { results = results.sort(); } else { results = results.sort(function sortUniqueArray(a, b) { return a[key] > b[key]; }); } } return results; } /** * get the prefixed property * @param {Object} obj * @param {String} property * @returns {String|Undefined} prefixed */ function prefixed(obj, property) { var prefix, prop; var camelProp = property[0].toUpperCase() + property.slice(1); var i = 0; while (i < VENDOR_PREFIXES.length) { prefix = VENDOR_PREFIXES[i]; prop = prefix ? prefix + camelProp : property; if (prop in obj) { return prop; } i++; } return undefined; } /** * get a unique id * @returns {number} uniqueId */ var _uniqueId = 1; function uniqueId() { return _uniqueId++; } /** * get the window object of an element * @param {HTMLElement} element * @returns {DocumentView|Window} */ function getWindowForElement(element) { var doc = element.ownerDocument || element; return doc.defaultView || doc.parentWindow || window; } var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i; var SUPPORT_TOUCH = 'ontouchstart' in window; var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined; var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent); var INPUT_TYPE_TOUCH = 'touch'; var INPUT_TYPE_PEN = 'pen'; var INPUT_TYPE_MOUSE = 'mouse'; var INPUT_TYPE_KINECT = 'kinect'; var COMPUTE_INTERVAL = 25; var INPUT_START = 1; var INPUT_MOVE = 2; var INPUT_END = 4; var INPUT_CANCEL = 8; var DIRECTION_NONE = 1; var DIRECTION_LEFT = 2; var DIRECTION_RIGHT = 4; var DIRECTION_UP = 8; var DIRECTION_DOWN = 16; var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT; var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN; var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL; var PROPS_XY = ['x', 'y']; var PROPS_CLIENT_XY = ['clientX', 'clientY']; /** * create new input type manager * @param {Manager} manager * @param {Function} callback * @returns {Input} * @constructor */ function Input(manager, callback) { var self = this; this.manager = manager; this.callback = callback; this.element = manager.element; this.target = manager.options.inputTarget; // smaller wrapper around the handler, for the scope and the enabled state of the manager, // so when disabled the input events are completely bypassed. this.domHandler = function (ev) { if (boolOrFn(manager.options.enable, [manager])) { self.handler(ev); } }; this.init(); } Input.prototype = { /** * should handle the inputEvent data and trigger the callback * @virtual */ handler: function handler() {}, /** * bind the events */ init: function init() { this.evEl && addEventListeners(this.element, this.evEl, this.domHandler); this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler); this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler); }, /** * unbind the events */ destroy: function destroy() { this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler); this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler); this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler); } }; /** * create new input type manager * called by the Manager constructor * @param {Hammer} manager * @returns {Input} */ function createInputInstance(manager) { var Type; var inputClass = manager.options.inputClass; if (inputClass) { Type = inputClass; } else if (SUPPORT_POINTER_EVENTS) { Type = PointerEventInput; } else if (SUPPORT_ONLY_TOUCH) { Type = TouchInput; } else if (!SUPPORT_TOUCH) { Type = MouseInput; } else { Type = TouchMouseInput; } return new Type(manager, inputHandler); } /** * handle input events * @param {Manager} manager * @param {String} eventType * @param {Object} input */ function inputHandler(manager, eventType, input) { var pointersLen = input.pointers.length; var changedPointersLen = input.changedPointers.length; var isFirst = eventType & INPUT_START && pointersLen - changedPointersLen === 0; var isFinal = eventType & (INPUT_END | INPUT_CANCEL) && pointersLen - changedPointersLen === 0; input.isFirst = !!isFirst; input.isFinal = !!isFinal; if (isFirst) { manager.session = {}; } // source event is the normalized value of the domEvents // like 'touchstart, mouseup, pointerdown' input.eventType = eventType; // compute scale, rotation etc computeInputData(manager, input); // emit secret event manager.emit('hammer.input', input); manager.recognize(input); manager.session.prevInput = input; } /** * extend the data with some usable properties like scale, rotate, velocity etc * @param {Object} manager * @param {Object} input */ function computeInputData(manager, input) { var session = manager.session; var pointers = input.pointers; var pointersLength = pointers.length; // store the first input to calculate the distance and direction if (!session.firstInput) { session.firstInput = simpleCloneInputData(input); } // to compute scale and rotation we need to store the multiple touches if (pointersLength > 1 && !session.firstMultiple) { session.firstMultiple = simpleCloneInputData(input); } else if (pointersLength === 1) { session.firstMultiple = false; } var firstInput = session.firstInput; var firstMultiple = session.firstMultiple; var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center; var center = input.center = getCenter(pointers); input.timeStamp = now(); input.deltaTime = input.timeStamp - firstInput.timeStamp; input.angle = getAngle(offsetCenter, center); input.distance = getDistance(offsetCenter, center); computeDeltaXY(session, input); input.offsetDirection = getDirection(input.deltaX, input.deltaY); var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY); input.overallVelocityX = overallVelocity.x; input.overallVelocityY = overallVelocity.y; input.overallVelocity = abs(overallVelocity.x) > abs(overallVelocity.y) ? overallVelocity.x : overallVelocity.y; input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1; input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0; input.maxPointers = !session.prevInput ? input.pointers.length : input.pointers.length > session.prevInput.maxPointers ? input.pointers.length : session.prevInput.maxPointers; computeIntervalInputData(session, input); // find the correct target var target = manager.element; if (hasParent(input.srcEvent.target, target)) { target = input.srcEvent.target; } input.target = target; } function computeDeltaXY(session, input) { var center = input.center; var offset = session.offsetDelta || {}; var prevDelta = session.prevDelta || {}; var prevInput = session.prevInput || {}; if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) { prevDelta = session.prevDelta = { x: prevInput.deltaX || 0, y: prevInput.deltaY || 0 }; offset = session.offsetDelta = { x: center.x, y: center.y }; } input.deltaX = prevDelta.x + (center.x - offset.x); input.deltaY = prevDelta.y + (center.y - offset.y); } /** * velocity is calculated every x ms * @param {Object} session * @param {Object} input */ function computeIntervalInputData(session, input) { var last = session.lastInterval || input, deltaTime = input.timeStamp - last.timeStamp, velocity, velocityX, velocityY, direction; if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) { var deltaX = input.deltaX - last.deltaX; var deltaY = input.deltaY - last.deltaY; var v = getVelocity(deltaTime, deltaX, deltaY); velocityX = v.x; velocityY = v.y; velocity = abs(v.x) > abs(v.y) ? v.x : v.y; direction = getDirection(deltaX, deltaY); session.lastInterval = input; } else { // use latest velocity info if it doesn't overtake a minimum period velocity = last.velocity; velocityX = last.velocityX; velocityY = last.velocityY; direction = last.direction; } input.velocity = velocity; input.velocityX = velocityX; input.velocityY = velocityY; input.direction = direction; } /** * create a simple clone from the input used for storage of firstInput and firstMultiple * @param {Object} input * @returns {Object} clonedInputData */ function simpleCloneInputData(input) { // make a simple copy of the pointers because we will get a reference if we don't // we only need clientXY for the calculations var pointers = []; var i = 0; while (i < input.pointers.length) { pointers[i] = { clientX: round(input.pointers[i].clientX), clientY: round(input.pointers[i].clientY) }; i++; } return { timeStamp: now(), pointers: pointers, center: getCenter(pointers), deltaX: input.deltaX, deltaY: input.deltaY }; } /** * get the center of all the pointers * @param {Array} pointers * @return {Object} center contains `x` and `y` properties */ function getCenter(pointers) { var pointersLength = pointers.length; // no need to loop when only one touch if (pointersLength === 1) { return { x: round(pointers[0].clientX), y: round(pointers[0].clientY) }; } var x = 0, y = 0, i = 0; while (i < pointersLength) { x += pointers[i].clientX; y += pointers[i].clientY; i++; } return { x: round(x / pointersLength), y: round(y / pointersLength) }; } /** * calculate the velocity between two points. unit is in px per ms. * @param {Number} deltaTime * @param {Number} x * @param {Number} y * @return {Object} velocity `x` and `y` */ function getVelocity(deltaTime, x, y) { return { x: x / deltaTime || 0, y: y / deltaTime || 0 }; } /** * get the direction between two points * @param {Number} x * @param {Number} y * @return {Number} direction */ function getDirection(x, y) { if (x === y) { return DIRECTION_NONE; } if (abs(x) >= abs(y)) { return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT; } return y < 0 ? DIRECTION_UP : DIRECTION_DOWN; } /** * calculate the absolute distance between two points * @param {Object} p1 {x, y} * @param {Object} p2 {x, y} * @param {Array} [props] containing x and y keys * @return {Number} distance */ function getDistance(p1, p2, props) { if (!props) { props = PROPS_XY; } var x = p2[props[0]] - p1[props[0]], y = p2[props[1]] - p1[props[1]]; return Math.sqrt(x * x + y * y); } /** * calculate the angle between two coordinates * @param {Object} p1 * @param {Object} p2 * @param {Array} [props] containing x and y keys * @return {Number} angle */ function getAngle(p1, p2, props) { if (!props) { props = PROPS_XY; } var x = p2[props[0]] - p1[props[0]], y = p2[props[1]] - p1[props[1]]; return Math.atan2(y, x) * 180 / Math.PI; } /** * calculate the rotation degrees between two pointersets * @param {Array} start array of pointers * @param {Array} end array of pointers * @return {Number} rotation */ function getRotation(start, end) { return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY); } /** * calculate the scale factor between two pointersets * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out * @param {Array} start array of pointers * @param {Array} end array of pointers * @return {Number} scale */ function getScale(start, end) { return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY); } var MOUSE_INPUT_MAP = { mousedown: INPUT_START, mousemove: INPUT_MOVE, mouseup: INPUT_END }; var MOUSE_ELEMENT_EVENTS = 'mousedown'; var MOUSE_WINDOW_EVENTS = 'mousemove mouseup'; /** * Mouse events input * @constructor * @extends Input */ function MouseInput() { this.evEl = MOUSE_ELEMENT_EVENTS; this.evWin = MOUSE_WINDOW_EVENTS; this.pressed = false; // mousedown state Input.apply(this, arguments); } inherit(MouseInput, Input, { /** * handle mouse events * @param {Object} ev */ handler: function MEhandler(ev) { var eventType = MOUSE_INPUT_MAP[ev.type]; // on start we want to have the left mouse button down if (eventType & INPUT_START && ev.button === 0) { this.pressed = true; } if (eventType & INPUT_MOVE && ev.which !== 1) { eventType = INPUT_END; } // mouse must be down if (!this.pressed) { return; } if (eventType & INPUT_END) { this.pressed = false; } this.callback(this.manager, eventType, { pointers: [ev], changedPointers: [ev], pointerType: INPUT_TYPE_MOUSE, srcEvent: ev }); } }); var POINTER_INPUT_MAP = { pointerdown: INPUT_START, pointermove: INPUT_MOVE, pointerup: INPUT_END, pointercancel: INPUT_CANCEL, pointerout: INPUT_CANCEL }; // in IE10 the pointer types is defined as an enum var IE10_POINTER_TYPE_ENUM = { 2: INPUT_TYPE_TOUCH, 3: INPUT_TYPE_PEN, 4: INPUT_TYPE_MOUSE, 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816 }; var POINTER_ELEMENT_EVENTS = 'pointerdown'; var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel'; // IE10 has prefixed support, and case-sensitive if (window.MSPointerEvent && !window.PointerEvent) { POINTER_ELEMENT_EVENTS = 'MSPointerDown'; POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel'; } /** * Pointer events input * @constructor * @extends Input */ function PointerEventInput() { this.evEl = POINTER_ELEMENT_EVENTS; this.evWin = POINTER_WINDOW_EVENTS; Input.apply(this, arguments); this.store = this.manager.session.pointerEvents = []; } inherit(PointerEventInput, Input, { /** * handle mouse events * @param {Object} ev */ handler: function PEhandler(ev) { var store = this.store; var removePointer = false; var eventTypeNormalized = ev.type.toLowerCase().replace('ms', ''); var eventType = POINTER_INPUT_MAP[eventTypeNormalized]; var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType; var isTouch = pointerType == INPUT_TYPE_TOUCH; // get index of the event in the store var storeIndex = inArray(store, ev.pointerId, 'pointerId'); // start and mouse must be down if (eventType & INPUT_START && (ev.button === 0 || isTouch)) { if (storeIndex < 0) { store.push(ev); storeIndex = store.length - 1; } } else if (eventType & (INPUT_END | INPUT_CANCEL)) { removePointer = true; } // it not found, so the pointer hasn't been down (so it's probably a hover) if (storeIndex < 0) { return; } // update the event in the store store[storeIndex] = ev; this.callback(this.manager, eventType, { pointers: store, changedPointers: [ev], pointerType: pointerType, srcEvent: ev }); if (removePointer) { // remove from the store store.splice(storeIndex, 1); } } }); var SINGLE_TOUCH_INPUT_MAP = { touchstart: INPUT_START, touchmove: INPUT_MOVE, touchend: INPUT_END, touchcancel: INPUT_CANCEL }; var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart'; var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel'; /** * Touch events input * @constructor * @extends Input */ function SingleTouchInput() { this.evTarget = SINGLE_TOUCH_TARGET_EVENTS; this.evWin = SINGLE_TOUCH_WINDOW_EVENTS; this.started = false; Input.apply(this, arguments); } inherit(SingleTouchInput, Input, { handler: function TEhandler(ev) { var type = SINGLE_TOUCH_INPUT_MAP[ev.type]; // should we handle the touch events? if (type === INPUT_START) { this.started = true; } if (!this.started) { return; } var touches = normalizeSingleTouches.call(this, ev, type); // when done, reset the started state if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) { this.started = false; } this.callback(this.manager, type, { pointers: touches[0], changedPointers: touches[1], pointerType: INPUT_TYPE_TOUCH, srcEvent: ev }); } }); /** * @this {TouchInput} * @param {Object} ev * @param {Number} type flag * @returns {undefined|Array} [all, changed] */ function normalizeSingleTouches(ev, type) { var all = toArray(ev.touches); var changed = toArray(ev.changedTouches); if (type & (INPUT_END | INPUT_CANCEL)) { all = uniqueArray(all.concat(changed), 'identifier', true); } return [all, changed]; } var TOUCH_INPUT_MAP = { touchstart: INPUT_START, touchmove: INPUT_MOVE, touchend: INPUT_END, touchcancel: INPUT_CANCEL }; var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel'; /** * Multi-user touch events input * @constructor * @extends Input */ function TouchInput() { this.evTarget = TOUCH_TARGET_EVENTS; this.targetIds = {}; Input.apply(this, arguments); } inherit(TouchInput, Input, { handler: function MTEhandler(ev) { var type = TOUCH_INPUT_MAP[ev.type]; var touches = getTouches.call(this, ev, type); if (!touches) { return; } this.callback(this.manager, type, { pointers: touches[0], changedPointers: touches[1], pointerType: INPUT_TYPE_TOUCH, srcEvent: ev }); } }); /** * @this {TouchInput} * @param {Object} ev * @param {Number} type flag * @returns {undefined|Array} [all, changed] */ function getTouches(ev, type) { var allTouches = toArray(ev.touches); var targetIds = this.targetIds; // when there is only one touch, the process can be simplified if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) { targetIds[allTouches[0].identifier] = true; return [allTouches, allTouches]; } var i, targetTouches, changedTouches = toArray(ev.changedTouches), changedTargetTouches = [], target = this.target; // get target touches from touches targetTouches = allTouches.filter(function (touch) { return hasParent(touch.target, target); }); // collect touches if (type === INPUT_START) { i = 0; while (i < targetTouches.length) { targetIds[targetTouches[i].identifier] = true; i++; } } // filter changed touches to only contain touches that exist in the collected target ids i = 0; while (i < changedTouches.length) { if (targetIds[changedTouches[i].identifier]) { changedTargetTouches.push(changedTouches[i]); } // cleanup removed touches if (type & (INPUT_END | INPUT_CANCEL)) { delete targetIds[changedTouches[i].identifier]; } i++; } if (!changedTargetTouches.length) { return; } return [ // merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel' uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true), changedTargetTouches]; } /** * Combined touch and mouse input * * Touch has a higher priority then mouse, and while touching no mouse events are allowed. * This because touch devices also emit mouse events while doing a touch. * * @constructor * @extends Input */ var DEDUP_TIMEOUT = 2500; var DEDUP_DISTANCE = 25; function TouchMouseInput() { Input.apply(this, arguments); var handler = bindFn(this.handler, this); this.touch = new TouchInput(this.manager, handler); this.mouse = new MouseInput(this.manager, handler); this.primaryTouch = null; this.lastTouches = []; } inherit(TouchMouseInput, Input, { /** * handle mouse and touch events * @param {Hammer} manager * @param {String} inputEvent * @param {Object} inputData */ handler: function TMEhandler(manager, inputEvent, inputData) { var isTouch = inputData.pointerType == INPUT_TYPE_TOUCH, isMouse = inputData.pointerType == INPUT_TYPE_MOUSE; if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) { return; } // when we're in a touch event, record touches to de-dupe synthetic mouse event if (isTouch) { recordTouches.call(this, inputEvent, inputData); } else if (isMouse && isSyntheticEvent.call(this, inputData)) { return; } this.callback(manager, inputEvent, inputData); }, /** * remove the event listeners */ destroy: function destroy() { this.touch.destroy(); this.mouse.destroy(); } }); function recordTouches(eventType, eventData) { if (eventType & INPUT_START) { this.primaryTouch = eventData.changedPointers[0].identifier; setLastTouch.call(this, eventData); } else if (eventType & (INPUT_END | INPUT_CANCEL)) { setLastTouch.call(this, eventData); } } function setLastTouch(eventData) { var touch = eventData.changedPointers[0]; if (touch.identifier === this.primaryTouch) { var lastTouch = { x: touch.clientX, y: touch.clientY }; this.lastTouches.push(lastTouch); var lts = this.lastTouches; var removeLastTouch = function removeLastTouch() { var i = lts.indexOf(lastTouch); if (i > -1) { lts.splice(i, 1); } }; setTimeout(removeLastTouch, DEDUP_TIMEOUT); } } function isSyntheticEvent(eventData) { var x = eventData.srcEvent.clientX, y = eventData.srcEvent.clientY; for (var i = 0; i < this.lastTouches.length; i++) { var t = this.lastTouches[i]; var dx = Math.abs(x - t.x), dy = Math.abs(y - t.y); if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) { return true; } } return false; } var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction'); var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined; // magical touchAction value var TOUCH_ACTION_COMPUTE = 'compute'; var TOUCH_ACTION_AUTO = 'auto'; var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented var TOUCH_ACTION_NONE = 'none'; var TOUCH_ACTION_PAN_X = 'pan-x'; var TOUCH_ACTION_PAN_Y = 'pan-y'; var TOUCH_ACTION_MAP = getTouchActionProps(); /** * Touch Action * sets the touchAction property or uses the js alternative * @param {Manager} manager * @param {String} value * @constructor */ function TouchAction(manager, value) { this.manager = manager; this.set(value); } TouchAction.prototype = { /** * set the touchAction value on the element or enable the polyfill * @param {String} value */ set: function set(value) { // find out the touch-action by the event handlers if (value == TOUCH_ACTION_COMPUTE) { value = this.compute(); } if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) { this.manager.element.style[PREFIXED_TOUCH_ACTION] = value; } this.actions = value.toLowerCase().trim(); }, /** * just re-set the touchAction value */ update: function update() { this.set(this.manager.options.touchAction); }, /** * compute the value for the touchAction property based on the recognizer's settings * @returns {String} value */ compute: function compute() { var actions = []; each(this.manager.recognizers, function (recognizer) { if (boolOrFn(recognizer.options.enable, [recognizer])) { actions = actions.concat(recognizer.getTouchAction()); } }); return cleanTouchActions(actions.join(' ')); }, /** * this method is called on each input cycle and provides the preventing of the browser behavior * @param {Object} input */ preventDefaults: function preventDefaults(input) { var srcEvent = input.srcEvent; var direction = input.offsetDirection; // if the touch action did prevented once this session if (this.manager.session.prevented) { srcEvent.preventDefault(); return; } var actions = this.actions; var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE]; var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y]; var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X]; if (hasNone) { //do not prevent defaults if this is a tap gesture var isTapPointer = input.pointers.length === 1; var isTapMovement = input.distance < 2; var isTapTouchTime = input.deltaTime < 250; if (isTapPointer && isTapMovement && isTapTouchTime) { return; } } if (hasPanX && hasPanY) { // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent return; } if (hasNone || hasPanY && direction & DIRECTION_HORIZONTAL || hasPanX && direction & DIRECTION_VERTICAL) { return this.preventSrc(srcEvent); } }, /** * call preventDefault to prevent the browser's default behavior (scrolling in most cases) * @param {Object} srcEvent */ preventSrc: function preventSrc(srcEvent) { this.manager.session.prevented = true; srcEvent.preventDefault(); } }; /** * when the touchActions are collected they are not a valid value, so we need to clean things up. * * @param {String} actions * @returns {*} */ function cleanTouchActions(actions) { // none if (inStr(actions, TOUCH_ACTION_NONE)) { return TOUCH_ACTION_NONE; } var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X); var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y); // if both pan-x and pan-y are set (different recognizers // for different directions, e.g. horizontal pan but vertical swipe?) // we need none (as otherwise with pan-x pan-y combined none of these // recognizers will work, since the browser would handle all panning if (hasPanX && hasPanY) { return TOUCH_ACTION_NONE; } // pan-x OR pan-y if (hasPanX || hasPanY) { return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y; } // manipulation if (inStr(actions, TOUCH_ACTION_MANIPULATION)) { return TOUCH_ACTION_MANIPULATION; } return TOUCH_ACTION_AUTO; } function getTouchActionProps() { if (!NATIVE_TOUCH_ACTION) { return false; } var touchMap = {}; var cssSupports = window.CSS && window.CSS.supports; ['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function (val) { // If css.supports is not supported but there is native touch-action assume it supports // all values. This is the case for IE 10 and 11. touchMap[val] = cssSupports ? window.CSS.supports('touch-action', val) : true; }); return touchMap; } /** * Recognizer flow explained; * * All recognizers have the initial state of POSSIBLE when a input session starts. * The definition of a input session is from the first input until the last input, with all it's movement in it. * * Example session for mouse-input: mousedown -> mousemove -> mouseup * * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed * which determines with state it should be. * * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to * POSSIBLE to give it another change on the next cycle. * * Possible * | * +-----+---------------+ * | | * +-----+-----+ | * | | | * Failed Cancelled | * +-------+------+ * | | * Recognized Began * | * Changed * | * Ended/Recognized */ var STATE_POSSIBLE = 1; var STATE_BEGAN = 2; var STATE_CHANGED = 4; var STATE_ENDED = 8; var STATE_RECOGNIZED = STATE_ENDED; var STATE_CANCELLED = 16; var STATE_FAILED = 32; /** * Recognizer * Every recognizer needs to extend from this class. * @constructor * @param {Object} options */ function Recognizer(options) { this.options = assign({}, this.defaults, options || {}); this.id = uniqueId(); this.manager = null; // default is enable true this.options.enable = ifUndefined(this.options.enable, true); this.state = STATE_POSSIBLE; this.simultaneous = {}; this.requireFail = []; } Recognizer.prototype = { /** * @virtual * @type {Object} */ defaults: {}, /** * set options * @param {Object} options * @return {Recognizer} */ set: function set(options) { assign(this.options, options); // also update the touchAction, in case something changed about the directions/enabled state this.manager && this.manager.touchAction.update(); return this; }, /** * recognize simultaneous with an other recognizer. * @param {Recognizer} otherRecognizer * @returns {Recognizer} this */ recognizeWith: function recognizeWith(otherRecognizer) { if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) { return this; } var simultaneous = this.simultaneous; otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); if (!simultaneous[otherRecognizer.id]) { simultaneous[otherRecognizer.id] = otherRecognizer; otherRecognizer.recognizeWith(this); } return this; }, /** * drop the simultaneous link. it doesnt remove the link on the other recognizer. * @param {Recognizer} otherRecognizer * @returns {Recognizer} this */ dropRecognizeWith: function dropRecognizeWith(otherRecognizer) { if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) { return this; } otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); delete this.simultaneous[otherRecognizer.id]; return this; }, /** * recognizer can only run when an other is failing * @param {Recognizer} otherRecognizer * @returns {Recognizer} this */ requireFailure: function requireFailure(otherRecognizer) { if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) { return this; } var requireFail = this.requireFail; otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); if (inArray(requireFail, otherRecognizer) === -1) { requireFail.push(otherRecognizer); otherRecognizer.requireFailure(this); } return this; }, /** * drop the requireFailure link. it does not remove the link on the other recognizer. * @param {Recognizer} otherRecognizer * @returns {Recognizer} this */ dropRequireFailure: function dropRequireFailure(otherRecognizer) { if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) { return this; } otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); var index = inArray(this.requireFail, otherRecognizer); if (index > -1) { this.requireFail.splice(index, 1); } return this; }, /** * has require failures boolean * @returns {boolean} */ hasRequireFailures: function hasRequireFailures() { return this.requireFail.length > 0; }, /** * if the recognizer can recognize simultaneous with an other recognizer * @param {Recognizer} otherRecognizer * @returns {Boolean} */ canRecognizeWith: function canRecognizeWith(otherRecognizer) { return !!this.simultaneous[otherRecognizer.id]; }, /** * You should use `tryEmit` instead of `emit` directly to check * that all the needed recognizers has failed before emitting. * @param {Object} input */ emit: function emit(input) { var self = this; var state = this.state; function emit(event) { self.manager.emit(event, input); } // 'panstart' and 'panmove' if (state < STATE_ENDED) { emit(self.options.event + stateStr(state)); } emit(self.options.event); // simple 'eventName' events if (input.additionalEvent) { // additional event(panleft, panright, pinchin, pinchout...) emit(input.additionalEvent); } // panend and pancancel if (state >= STATE_ENDED) { emit(self.options.event + stateStr(state)); } }, /** * Check that all the require failure recognizers has failed, * if true, it emits a gesture event, * otherwise, setup the state to FAILED. * @param {Object} input */ tryEmit: function tryEmit(input) { if (this.canEmit()) { return this.emit(input); } // it's failing anyway this.state = STATE_FAILED; }, /** * can we emit? * @returns {boolean} */ canEmit: function canEmit() { var i = 0; while (i < this.requireFail.length) { if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) { return false; } i++; } return true; }, /** * update the recognizer * @param {Object} inputData */ recognize: function recognize(inputData) { // make a new copy of the inputData // so we can change the inputData without messing up the other recognizers var inputDataClone = assign({}, inputData); // is is enabled and allow recognizing? if (!boolOrFn(this.options.enable, [this, inputDataClone])) { this.reset(); this.state = STATE_FAILED; return; } // reset when we've reached the end if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) { this.state = STATE_POSSIBLE; } this.state = this.process(inputDataClone); // the recognizer has recognized a gesture // so trigger an event if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) { this.tryEmit(inputDataClone); } }, /** * return the state of the recognizer * the actual recognizing happens in this method * @virtual * @param {Object} inputData * @returns {Const} STATE */ process: function process(inputData) {}, // jshint ignore:line /** * return the preferred touch-action * @virtual * @returns {Array} */ getTouchAction: function getTouchAction() {}, /** * called when the gesture isn't allowed to recognize * like when another is being recognized or it is disabled * @virtual */ reset: function reset() {} }; /** * get a usable string, used as event postfix * @param {Const} state * @returns {String} state */ function stateStr(state) { if (state & STATE_CANCELLED) { return 'cancel'; } else if (state & STATE_ENDED) { return 'end'; } else if (state & STATE_CHANGED) { return 'move'; } else if (state & STATE_BEGAN) { return 'start'; } return ''; } /** * direction cons to string * @param {Const} direction * @returns {String} */ function directionStr(direction) { if (direction == DIRECTION_DOWN) { return 'down'; } else if (direction == DIRECTION_UP) { return 'up'; } else if (direction == DIRECTION_LEFT) { return 'left'; } else if (direction == DIRECTION_RIGHT) { return 'right'; } return ''; } /** * get a recognizer by name if it is bound to a manager * @param {Recognizer|String} otherRecognizer * @param {Recognizer} recognizer * @returns {Recognizer} */ function getRecognizerByNameIfManager(otherRecognizer, recognizer) { var manager = recognizer.manager; if (manager) { return manager.get(otherRecognizer); } return otherRecognizer; } /** * This recognizer is just used as a base for the simple attribute recognizers. * @constructor * @extends Recognizer */ function AttrRecognizer() { Recognizer.apply(this, arguments); } inherit(AttrRecognizer, Recognizer, { /** * @namespace * @memberof AttrRecognizer */ defaults: { /** * @type {Number} * @default 1 */ pointers: 1 }, /** * Used to check if it the recognizer receives valid input, like input.distance > 10. * @memberof AttrRecognizer * @param {Object} input * @returns {Boolean} recognized */ attrTest: function attrTest(input) { var optionPointers = this.options.pointers; return optionPointers === 0 || input.pointers.length === optionPointers; }, /** * Process the input and return the state for the recognizer * @memberof AttrRecognizer * @param {Object} input * @returns {*} State */ process: function process(input) { var state = this.state; var eventType = input.eventType; var isRecognized = state & (STATE_BEGAN | STATE_CHANGED); var isValid = this.attrTest(input); // on cancel input and we've recognized before, return STATE_CANCELLED if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) { return state | STATE_CANCELLED; } else if (isRecognized || isValid) { if (eventType & INPUT_END) { return state | STATE_ENDED; } else if (!(state & STATE_BEGAN)) { return STATE_BEGAN; } return state | STATE_CHANGED; } return STATE_FAILED; } }); /** * Pan * Recognized when the pointer is down and moved in the allowed direction. * @constructor * @extends AttrRecognizer */ function PanRecognizer() { AttrRecognizer.apply(this, arguments); this.pX = null; this.pY = null; } inherit(PanRecognizer, AttrRecognizer, { /** * @namespace * @memberof PanRecognizer */ defaults: { event: 'pan', threshold: 10, pointers: 1, direction: DIRECTION_ALL }, getTouchAction: function getTouchAction() { var direction = this.options.direction; var actions = []; if (direction & DIRECTION_HORIZONTAL) { actions.push(TOUCH_ACTION_PAN_Y); } if (direction & DIRECTION_VERTICAL) { actions.push(TOUCH_ACTION_PAN_X); } return actions; }, directionTest: function directionTest(input) { var options = this.options; var hasMoved = true; var distance = input.distance; var direction = input.direction; var x = input.deltaX; var y = input.deltaY; // lock to axis? if (!(direction & options.direction)) { if (options.direction & DIRECTION_HORIZONTAL) { direction = x === 0 ? DIRECTION_NONE : x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT; hasMoved = x != this.pX; distance = Math.abs(input.deltaX); } else { direction = y === 0 ? DIRECTION_NONE : y < 0 ? DIRECTION_UP : DIRECTION_DOWN; hasMoved = y != this.pY; distance = Math.abs(input.deltaY); } } input.direction = direction; return hasMoved && distance > options.threshold && direction & options.direction; }, attrTest: function attrTest(input) { return AttrRecognizer.prototype.attrTest.call(this, input) && (this.state & STATE_BEGAN || !(this.state & STATE_BEGAN) && this.directionTest(input)); }, emit: function emit(input) { this.pX = input.deltaX; this.pY = input.deltaY; var direction = directionStr(input.direction); if (direction) { input.additionalEvent = this.options.event + direction; } this._super.emit.call(this, input); } }); /** * Pinch * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out). * @constructor * @extends AttrRecognizer */ function PinchRecognizer() { AttrRecognizer.apply(this, arguments); } inherit(PinchRecognizer, AttrRecognizer, { /** * @namespace * @memberof PinchRecognizer */ defaults: { event: 'pinch', threshold: 0, pointers: 2 }, getTouchAction: function getTouchAction() { return [TOUCH_ACTION_NONE]; }, attrTest: function attrTest(input) { return this._super.attrTest.call(this, input) && (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN); }, emit: function emit(input) { if (input.scale !== 1) { var inOut = input.scale < 1 ? 'in' : 'out'; input.additionalEvent = this.options.event + inOut; } this._super.emit.call(this, input); } }); /** * Press * Recognized when the pointer is down for x ms without any movement. * @constructor * @extends Recognizer */ function PressRecognizer() { Recognizer.apply(this, arguments); this._timer = null; this._input = null; } inherit(PressRecognizer, Recognizer, { /** * @namespace * @memberof PressRecognizer */ defaults: { event: 'press', pointers: 1, time: 251, // minimal time of the pointer to be pressed threshold: 9 // a minimal movement is ok, but keep it low }, getTouchAction: function getTouchAction() { return [TOUCH_ACTION_AUTO]; }, process: function process(input) { var options = this.options; var validPointers = input.pointers.length === options.pointers; var validMovement = input.distance < options.threshold; var validTime = input.deltaTime > options.time; this._input = input; // we only allow little movement // and we've reached an end event, so a tap is possible if (!validMovement || !validPointers || input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime) { this.reset(); } else if (input.eventType & INPUT_START) { this.reset(); this._timer = setTimeoutContext(function () { this.state = STATE_RECOGNIZED; this.tryEmit(); }, options.time, this); } else if (input.eventType & INPUT_END) { return STATE_RECOGNIZED; } return STATE_FAILED; }, reset: function reset() { clearTimeout(this._timer); }, emit: function emit(input) { if (this.state !== STATE_RECOGNIZED) { return; } if (input && input.eventType & INPUT_END) { this.manager.emit(this.options.event + 'up', input); } else { this._input.timeStamp = now(); this.manager.emit(this.options.event, this._input); } } }); /** * Rotate * Recognized when two or more pointer are moving in a circular motion. * @constructor * @extends AttrRecognizer */ function RotateRecognizer() { AttrRecognizer.apply(this, arguments); } inherit(RotateRecognizer, AttrRecognizer, { /** * @namespace * @memberof RotateRecognizer */ defaults: { event: 'rotate', threshold: 0, pointers: 2 }, getTouchAction: function getTouchAction() { return [TOUCH_ACTION_NONE]; }, attrTest: function attrTest(input) { return this._super.attrTest.call(this, input) && (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN); } }); /** * Swipe * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction. * @constructor * @extends AttrRecognizer */ function SwipeRecognizer() { AttrRecognizer.apply(this, arguments); } inherit(SwipeRecognizer, AttrRecognizer, { /** * @namespace * @memberof SwipeRecognizer */ defaults: { event: 'swipe', threshold: 10, velocity: 0.3, direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL, pointers: 1 }, getTouchAction: function getTouchAction() { return PanRecognizer.prototype.getTouchAction.call(this); }, attrTest: function attrTest(input) { var direction = this.options.direction; var velocity; if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) { velocity = input.overallVelocity; } else if (direction & DIRECTION_HORIZONTAL) { velocity = input.overallVelocityX; } else if (direction & DIRECTION_VERTICAL) { velocity = input.overallVelocityY; } return this._super.attrTest.call(this, input) && direction & input.offsetDirection && input.distance > this.options.threshold && input.maxPointers == this.options.pointers && abs(velocity) > this.options.velocity && input.eventType & INPUT_END; }, emit: function emit(input) { var direction = directionStr(input.offsetDirection); if (direction) { this.manager.emit(this.options.event + direction, input); } this.manager.emit(this.options.event, input); } }); /** * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur * between the given interval and position. The delay option can be used to recognize multi-taps without firing * a single tap. * * The eventData from the emitted event contains the property `tapCount`, which contains the amount of * multi-taps being recognized. * @constructor * @extends Recognizer */ function TapRecognizer() { Recognizer.apply(this, arguments); // previous time and center, // used for tap counting this.pTime = false; this.pCenter = false; this._timer = null; this._input = null; this.count = 0; } inherit(TapRecognizer, Recognizer, { /** * @namespace * @memberof PinchRecognizer */ defaults: { event: 'tap', pointers: 1, taps: 1, interval: 300, // max time between the multi-tap taps time: 250, // max time of the pointer to be down (like finger on the screen) threshold: 9, // a minimal movement is ok, but keep it low posThreshold: 10 // a multi-tap can be a bit off the initial position }, getTouchAction: function getTouchAction() { return [TOUCH_ACTION_MANIPULATION]; }, process: function process(input) { var options = this.options; var validPointers = input.pointers.length === options.pointers; var validMovement = input.distance < options.threshold; var validTouchTime = input.deltaTime < options.time; this.reset(); if (input.eventType & INPUT_START && this.count === 0) { return this.failTimeout(); } // we only allow little movement // and we've reached an end event, so a tap is possible if (validMovement && validTouchTime && validPointers) { if (input.eventType != INPUT_END) { return this.failTimeout(); } var validInterval = this.pTime ? input.timeStamp - this.pTime < options.interval : true; var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold; this.pTime = input.timeStamp; this.pCenter = input.center; if (!validMultiTap || !validInterval) { this.count = 1; } else { this.count += 1; } this._input = input; // if tap count matches we have recognized it, // else it has began recognizing... var tapCount = this.count % options.taps; if (tapCount === 0) { // no failing requirements, immediately trigger the tap event // or wait as long as the multitap interval to trigger if (!this.hasRequireFailures()) { return STATE_RECOGNIZED; } else { this._timer = setTimeoutContext(function () { this.state = STATE_RECOGNIZED; this.tryEmit(); }, options.interval, this); return STATE_BEGAN; } } } return STATE_FAILED; }, failTimeout: function failTimeout() { this._timer = setTimeoutContext(function () { this.state = STATE_FAILED; }, this.options.interval, this); return STATE_FAILED; }, reset: function reset() { clearTimeout(this._timer); }, emit: function emit() { if (this.state == STATE_RECOGNIZED) { this._input.tapCount = this.count; this.manager.emit(this.options.event, this._input); } } }); /** * Simple way to create a manager with a default set of recognizers. * @param {HTMLElement} element * @param {Object} [options] * @constructor */ function Hammer(element, options) { options = options || {}; options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset); return new Manager(element, options); } /** * @const {string} */ Hammer.VERSION = '2.0.7'; /** * default settings * @namespace */ Hammer.defaults = { /** * set if DOM events are being triggered. * But this is slower and unused by simple implementations, so disabled by default. * @type {Boolean} * @default false */ domEvents: false, /** * The value for the touchAction property/fallback. * When set to `compute` it will magically set the correct value based on the added recognizers. * @type {String} * @default compute */ touchAction: TOUCH_ACTION_COMPUTE, /** * @type {Boolean} * @default true */ enable: true, /** * EXPERIMENTAL FEATURE -- can be removed/changed * Change the parent input target element. * If Null, then it is being set the to main element. * @type {Null|EventTarget} * @default null */ inputTarget: null, /** * force an input class * @type {Null|Function} * @default null */ inputClass: null, /** * Default recognizer setup when calling `Hammer()` * When creating a new Manager these will be skipped. * @type {Array} */ preset: [ // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...] [RotateRecognizer, { enable: false }], [PinchRecognizer, { enable: false }, ['rotate']], [SwipeRecognizer, { direction: DIRECTION_HORIZONTAL }], [PanRecognizer, { direction: DIRECTION_HORIZONTAL }, ['swipe']], [TapRecognizer], [TapRecognizer, { event: 'doubletap', taps: 2 }, ['tap']], [PressRecognizer]], /** * Some CSS properties can be used to improve the working of Hammer. * Add them to this method and they will be set when creating a new Manager. * @namespace */ cssProps: { /** * Disables text selection to improve the dragging gesture. Mainly for desktop browsers. * @type {String} * @default 'none' */ userSelect: 'none', /** * Disable the Windows Phone grippers when pressing an element. * @type {String} * @default 'none' */ touchSelect: 'none', /** * Disables the default callout shown when you touch and hold a touch target. * On iOS, when you touch and hold a touch target such as a link, Safari displays * a callout containing information about the link. This property allows you to disable that callout. * @type {String} * @default 'none' */ touchCallout: 'none', /** * Specifies whether zooming is enabled. Used by IE10> * @type {String} * @default 'none' */ contentZooming: 'none', /** * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers. * @type {String} * @default 'none' */ userDrag: 'none', /** * Overrides the highlight color shown when the user taps a link or a JavaScript * clickable element in iOS. This property obeys the alpha value, if specified. * @type {String} * @default 'rgba(0,0,0,0)' */ tapHighlightColor: 'rgba(0,0,0,0)' } }; var STOP = 1; var FORCED_STOP = 2; /** * Manager * @param {HTMLElement} element * @param {Object} [options] * @constructor */ function Manager(element, options) { this.options = assign({}, Hammer.defaults, options || {}); this.options.inputTarget = this.options.inputTarget || element; this.handlers = {}; this.session = {}; this.recognizers = []; this.oldCssProps = {}; this.element = element; this.input = createInputInstance(this); this.touchAction = new TouchAction(this, this.options.touchAction); toggleCssProps(this, true); each(this.options.recognizers, function (item) { var recognizer = this.add(new item[0](item[1])); item[2] && recognizer.recognizeWith(item[2]); item[3] && recognizer.requireFailure(item[3]); }, this); } Manager.prototype = { /** * set options * @param {Object} options * @returns {Manager} */ set: function set(options) { assign(this.options, options); // Options that need a little more setup if (options.touchAction) { this.touchAction.update(); } if (options.inputTarget) { // Clean up existing event listeners and reinitialize this.input.destroy(); this.input.target = options.inputTarget; this.input.init(); } return this; }, /** * stop recognizing for this session. * This session will be discarded, when a new [input]start event is fired. * When forced, the recognizer cycle is stopped immediately. * @param {Boolean} [force] */ stop: function stop(force) { this.session.stopped = force ? FORCED_STOP : STOP; }, /** * run the recognizers! * called by the inputHandler function on every movement of the pointers (touches) * it walks through all the recognizers and tries to detect the gesture that is being made * @param {Object} inputData */ recognize: function recognize(inputData) { var session = this.session; if (session.stopped) { return; } // run the touch-action polyfill this.touchAction.preventDefaults(inputData); var recognizer; var recognizers = this.recognizers; // this holds the recognizer that is being recognized. // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED // if no recognizer is detecting a thing, it is set to `null` var curRecognizer = session.curRecognizer; // reset when the last recognizer is recognized // or when we're in a new session if (!curRecognizer || curRecognizer && curRecognizer.state & STATE_RECOGNIZED) { curRecognizer = session.curRecognizer = null; } var i = 0; while (i < recognizers.length) { recognizer = recognizers[i]; // find out if we are allowed try to recognize the input for this one. // 1. allow if the session is NOT forced stopped (see the .stop() method) // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one // that is being recognized. // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer. // this can be setup with the `recognizeWith()` method on the recognizer. if (session.stopped !== FORCED_STOP && ( // 1 !curRecognizer || recognizer == curRecognizer || // 2 recognizer.canRecognizeWith(curRecognizer))) { // 3 recognizer.recognize(inputData); } else { recognizer.reset(); } // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the // current active recognizer. but only if we don't already have an active recognizer if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) { curRecognizer = session.curRecognizer = recognizer; } i++; } }, /** * get a recognizer by its event name. * @param {Recognizer|String} recognizer * @returns {Recognizer|Null} */ get: function get(recognizer) { if (recognizer instanceof Recognizer) { return recognizer; } var recognizers = this.recognizers; for (var i = 0; i < recognizers.length; i++) { if (recognizers[i].options.event == recognizer) { return recognizers[i]; } } return null; }, /** * add a recognizer to the manager * existing recognizers with the same event name will be removed * @param {Recognizer} recognizer * @returns {Recognizer|Manager} */ add: function add(recognizer) { if (invokeArrayArg(recognizer, 'add', this)) { return this; } // remove existing var existing = this.get(recognizer.options.event); if (existing) { this.remove(existing); } this.recognizers.push(recognizer); recognizer.manager = this; this.touchAction.update(); return recognizer; }, /** * remove a recognizer by name or instance * @param {Recognizer|String} recognizer * @returns {Manager} */ remove: function remove(recognizer) { if (invokeArrayArg(recognizer, 'remove', this)) { return this; } recognizer = this.get(recognizer); // let's make sure this recognizer exists if (recognizer) { var recognizers = this.recognizers; var index = inArray(recognizers, recognizer); if (index !== -1) { recognizers.splice(index, 1); this.touchAction.update(); } } return this; }, /** * bind event * @param {String} events * @param {Function} handler * @returns {EventEmitter} this */ on: function on(events, handler) { if (events === undefined) { return; } if (handler === undefined) { return; } var handlers = this.handlers; each(splitStr(events), function (event) { handlers[event] = handlers[event] || []; handlers[event].push(handler); }); return this; }, /** * unbind event, leave emit blank to remove all handlers * @param {String} events * @param {Function} [handler] * @returns {EventEmitter} this */ off: function off(events, handler) { if (events === undefined) { return; } var handlers = this.handlers; each(splitStr(events), function (event) { if (!handler) { delete handlers[event]; } else { handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1); } }); return this; }, /** * emit event to the listeners * @param {String} event * @param {Object} data */ emit: function emit(event, data) { // we also want to trigger dom events if (this.options.domEvents) { triggerDomEvent(event, data); } // no handlers, so skip it all var handlers = this.handlers[event] && this.handlers[event].slice(); if (!handlers || !handlers.length) { return; } data.type = event; data.preventDefault = function () { data.srcEvent.preventDefault(); }; var i = 0; while (i < handlers.length) { handlers[i](data); i++; } }, /** * destroy the manager and unbinds all events * it doesn't unbind dom events, that is the user own responsibility */ destroy: function destroy() { this.element && toggleCssProps(this, false); this.handlers = {}; this.session = {}; this.input.destroy(); this.element = null; } }; /** * add/remove the css properties as defined in manager.options.cssProps * @param {Manager} manager * @param {Boolean} add */ function toggleCssProps(manager, add) { var element = manager.element; if (!element.style) { return; } var prop; each(manager.options.cssProps, function (value, name) { prop = prefixed(element.style, name); if (add) { manager.oldCssProps[prop] = element.style[prop]; element.style[prop] = value; } else { element.style[prop] = manager.oldCssProps[prop] || ''; } }); if (!add) { manager.oldCssProps = {}; } } /** * trigger dom event * @param {String} event * @param {Object} data */ function triggerDomEvent(event, data) { var gestureEvent = document.createEvent('Event'); gestureEvent.initEvent(event, true, true); gestureEvent.gesture = data; data.target.dispatchEvent(gestureEvent); } assign(Hammer, { INPUT_START: INPUT_START, INPUT_MOVE: INPUT_MOVE, INPUT_END: INPUT_END, INPUT_CANCEL: INPUT_CANCEL, STATE_POSSIBLE: STATE_POSSIBLE, STATE_BEGAN: STATE_BEGAN, STATE_CHANGED: STATE_CHANGED, STATE_ENDED: STATE_ENDED, STATE_RECOGNIZED: STATE_RECOGNIZED, STATE_CANCELLED: STATE_CANCELLED, STATE_FAILED: STATE_FAILED, DIRECTION_NONE: DIRECTION_NONE, DIRECTION_LEFT: DIRECTION_LEFT, DIRECTION_RIGHT: DIRECTION_RIGHT, DIRECTION_UP: DIRECTION_UP, DIRECTION_DOWN: DIRECTION_DOWN, DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL, DIRECTION_VERTICAL: DIRECTION_VERTICAL, DIRECTION_ALL: DIRECTION_ALL, Manager: Manager, Input: Input, TouchAction: TouchAction, TouchInput: TouchInput, MouseInput: MouseInput, PointerEventInput: PointerEventInput, TouchMouseInput: TouchMouseInput, SingleTouchInput: SingleTouchInput, Recognizer: Recognizer, AttrRecognizer: AttrRecognizer, Tap: TapRecognizer, Pan: PanRecognizer, Swipe: SwipeRecognizer, Pinch: PinchRecognizer, Rotate: RotateRecognizer, Press: PressRecognizer, on: addEventListeners, off: removeEventListeners, each: each, merge: merge, extend: extend, assign: assign, inherit: inherit, bindFn: bindFn, prefixed: prefixed }); // this prevents errors when Hammer is loaded in the presence of an AMD // style loader but by script tag, not by the loader. var freeGlobal = typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}; // jshint ignore:line freeGlobal.Hammer = Hammer; if (typeof define === 'function' && define.amd) { define(function () { return Hammer; }); } else if (typeof module != 'undefined' && module.exports) { module.exports = Hammer; } else { window[exportName] = Hammer; } })(window, document, 'Hammer'); },{}],413:[function(require,module,exports){ 'use strict'; var hat = module.exports = function (bits, base) { if (!base) base = 16; if (bits === undefined) bits = 128; if (bits <= 0) return '0'; var digits = Math.log(Math.pow(2, bits)) / Math.log(base); for (var i = 2; digits === Infinity; i *= 2) { digits = Math.log(Math.pow(2, bits / i)) / Math.log(base) * i; } var rem = digits - Math.floor(digits); var res = ''; for (var i = 0; i < Math.floor(digits); i++) { var x = Math.floor(Math.random() * base).toString(base); res = x + res; } if (rem) { var b = Math.pow(base, rem); var x = Math.floor(Math.random() * b).toString(base); res = x + res; } var parsed = parseInt(res, base); if (parsed !== Infinity && parsed >= Math.pow(2, bits)) { return hat(bits, base); } else return res; }; hat.rack = function (bits, base, expandBy) { var fn = function fn(data) { var iters = 0; do { if (iters++ > 10) { if (expandBy) bits += expandBy;else throw new Error('too many ID collisions, use more bits'); } var id = hat(bits, base); } while (Object.hasOwnProperty.call(hats, id)); hats[id] = data; return id; }; var hats = fn.hats = {}; fn.get = function (id) { return fn.hats[id]; }; fn.set = function (id, value) { fn.hats[id] = value; return fn; }; fn.bits = bits || 128; fn.base = base || 16; return fn; }; },{}],414:[function(require,module,exports){ 'use strict'; var hat = require('hat'); /** * Create a new id generator / cache instance. * * You may optionally provide a seed that is used internally. * * @param {Seed} seed */ function Ids(seed) { if (!(this instanceof Ids)) { return new Ids(seed); } seed = seed || [128, 36, 1]; this._seed = seed.length ? hat.rack(seed[0], seed[1], seed[2]) : seed; } module.exports = Ids; /** * Generate a next id. * * @param {Object} [element] element to bind the id to * * @return {String} id */ Ids.prototype.next = function (element) { return this._seed(element || true); }; /** * Generate a next id with a given prefix. * * @param {Object} [element] element to bind the id to * * @return {String} id */ Ids.prototype.nextPrefixed = function (prefix, element) { var id; do { id = prefix + this.next(true); } while (this.assigned(id)); // claim {prefix}{random} this.claim(id, element); // return return id; }; /** * Manually claim an existing id. * * @param {String} id * @param {String} [element] element the id is claimed by */ Ids.prototype.claim = function (id, element) { this._seed.set(id, element || true); }; /** * Returns true if the given id has already been assigned. * * @param {String} id * @return {Boolean} */ Ids.prototype.assigned = function (id) { return this._seed.get(id) || false; }; /** * Unclaim an id. * * @param {String} id the id to unclaim */ Ids.prototype.unclaim = function (id) { delete this._seed.hats[id]; }; /** * Clear all claimed ids. */ Ids.prototype.clear = function () { var hats = this._seed.hats, id; for (id in hats) { this.unclaim(id); } }; },{"hat":413}],415:[function(require,module,exports){ 'use strict'; 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() {}; TempCtor.prototype = superCtor.prototype; ctor.prototype = new TempCtor(); ctor.prototype.constructor = ctor; }; } },{}],416:[function(require,module,exports){ "use strict"; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /*! * jQuery JavaScript Library v3.3.1 * https://jquery.com/ * * Includes Sizzle.js * https://sizzlejs.com/ * * Copyright JS Foundation and other contributors * Released under the MIT license * https://jquery.org/license * * Date: 2018-01-20T17:24Z */ (function (global, factory) { "use strict"; if ((typeof module === "undefined" ? "undefined" : _typeof(module)) === "object" && _typeof(module.exports) === "object") { // For CommonJS and CommonJS-like environments where a proper `window` // is present, execute the factory and get jQuery. // For environments that do not have a `window` with a `document` // (such as Node.js), expose a factory as module.exports. // This accentuates the need for the creation of a real `window`. // e.g. var jQuery = require("jquery")(window); // See ticket #14549 for more info. module.exports = global.document ? factory(global, true) : function (w) { if (!w.document) { throw new Error("jQuery requires a window with a document"); } return factory(w); }; } else { factory(global); } // Pass this if window is not defined yet })(typeof window !== "undefined" ? window : undefined, function (window, noGlobal) { // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common // enough that all such attempts are guarded in a try block. "use strict"; var arr = []; var document = window.document; var getProto = Object.getPrototypeOf; var _slice = arr.slice; var concat = arr.concat; var push = arr.push; var indexOf = arr.indexOf; var class2type = {}; var toString = class2type.toString; var hasOwn = class2type.hasOwnProperty; var fnToString = hasOwn.toString; var ObjectFunctionString = fnToString.call(Object); var support = {}; var isFunction = function isFunction(obj) { // Support: Chrome <=57, Firefox <=52 // In some browsers, typeof returns "function" for HTML elements // (i.e., `typeof document.createElement( "object" ) === "function"`). // We don't want to classify *any* DOM node as a function. return typeof obj === "function" && typeof obj.nodeType !== "number"; }; var isWindow = function isWindow(obj) { return obj != null && obj === obj.window; }; var preservedScriptAttributes = { type: true, src: true, noModule: true }; function DOMEval(code, doc, node) { doc = doc || document; var i, script = doc.createElement("script"); script.text = code; if (node) { for (i in preservedScriptAttributes) { if (node[i]) { script[i] = node[i]; } } } doc.head.appendChild(script).parentNode.removeChild(script); } function toType(obj) { if (obj == null) { return obj + ""; } // Support: Android <=2.3 only (functionish RegExp) return (typeof obj === "undefined" ? "undefined" : _typeof(obj)) === "object" || typeof obj === "function" ? class2type[toString.call(obj)] || "object" : typeof obj === "undefined" ? "undefined" : _typeof(obj); } /* global Symbol */ // Defining this global in .eslintrc.json would create a danger of using the global // unguarded in another place, it seems safer to define global only for this module var version = "3.3.1", // Define a local copy of jQuery jQuery = function jQuery(selector, context) { // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQuery.fn.init(selector, context); }, // Support: Android <=4.0 only // Make sure we trim BOM and NBSP rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; jQuery.fn = jQuery.prototype = { // The current version of jQuery being used jquery: version, constructor: jQuery, // The default length of a jQuery object is 0 length: 0, toArray: function toArray() { return _slice.call(this); }, // Get the Nth element in the matched element set OR // Get the whole matched element set as a clean array get: function get(num) { // Return all the elements in a clean array if (num == null) { return _slice.call(this); } // Return just the one element from the set return num < 0 ? this[num + this.length] : this[num]; }, // Take an array of elements and push it onto the stack // (returning the new matched element set) pushStack: function pushStack(elems) { // Build a new jQuery matched element set var ret = jQuery.merge(this.constructor(), elems); // Add the old object onto the stack (as a reference) ret.prevObject = this; // Return the newly-formed element set return ret; }, // Execute a callback for every element in the matched set. each: function each(callback) { return jQuery.each(this, callback); }, map: function map(callback) { return this.pushStack(jQuery.map(this, function (elem, i) { return callback.call(elem, i, elem); })); }, slice: function slice() { return this.pushStack(_slice.apply(this, arguments)); }, first: function first() { return this.eq(0); }, last: function last() { return this.eq(-1); }, eq: function eq(i) { var len = this.length, j = +i + (i < 0 ? len : 0); return this.pushStack(j >= 0 && j < len ? [this[j]] : []); }, end: function end() { return this.prevObject || this.constructor(); }, // For internal use only. // Behaves like an Array's method, not like a jQuery method. push: push, sort: arr.sort, splice: arr.splice }; jQuery.extend = jQuery.fn.extend = function () { var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if (typeof target === "boolean") { deep = target; // Skip the boolean and the target target = arguments[i] || {}; i++; } // Handle case when target is a string or something (possible in deep copy) if ((typeof target === "undefined" ? "undefined" : _typeof(target)) !== "object" && !isFunction(target)) { target = {}; } // Extend jQuery itself if only one argument is passed if (i === length) { target = this; i--; } for (; i < length; i++) { // Only deal with non-null/undefined values if ((options = arguments[i]) != null) { // Extend the base object for (name in options) { src = target[name]; copy = options[name]; // Prevent never-ending loop if (target === copy) { continue; } // Recurse if we're merging plain objects or arrays if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) { if (copyIsArray) { copyIsArray = false; clone = src && Array.isArray(src) ? src : []; } else { clone = src && jQuery.isPlainObject(src) ? src : {}; } // Never move original objects, clone them target[name] = jQuery.extend(deep, clone, copy); // Don't bring in undefined values } else if (copy !== undefined) { target[name] = copy; } } } } // Return the modified object return target; }; jQuery.extend({ // Unique for each copy of jQuery on the page expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""), // Assume jQuery is ready without the ready module isReady: true, error: function error(msg) { throw new Error(msg); }, noop: function noop() {}, isPlainObject: function isPlainObject(obj) { var proto, Ctor; // Detect obvious negatives // Use toString instead of jQuery.type to catch host objects if (!obj || toString.call(obj) !== "[object Object]") { return false; } proto = getProto(obj); // Objects with no prototype (e.g., `Object.create( null )`) are plain if (!proto) { return true; } // Objects with prototype are plain iff they were constructed by a global Object function Ctor = hasOwn.call(proto, "constructor") && proto.constructor; return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString; }, isEmptyObject: function isEmptyObject(obj) { /* eslint-disable no-unused-vars */ // See https://github.com/eslint/eslint/issues/6125 var name; for (name in obj) { return false; } return true; }, // Evaluates a script in a global context globalEval: function globalEval(code) { DOMEval(code); }, each: function each(obj, callback) { var length, i = 0; if (isArrayLike(obj)) { length = obj.length; for (; i < length; i++) { if (callback.call(obj[i], i, obj[i]) === false) { break; } } } else { for (i in obj) { if (callback.call(obj[i], i, obj[i]) === false) { break; } } } return obj; }, // Support: Android <=4.0 only trim: function trim(text) { return text == null ? "" : (text + "").replace(rtrim, ""); }, // results is for internal usage only makeArray: function makeArray(arr, results) { var ret = results || []; if (arr != null) { if (isArrayLike(Object(arr))) { jQuery.merge(ret, typeof arr === "string" ? [arr] : arr); } else { push.call(ret, arr); } } return ret; }, inArray: function inArray(elem, arr, i) { return arr == null ? -1 : indexOf.call(arr, elem, i); }, // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit merge: function merge(first, second) { var len = +second.length, j = 0, i = first.length; for (; j < len; j++) { first[i++] = second[j]; } first.length = i; return first; }, grep: function grep(elems, callback, invert) { var callbackInverse, matches = [], i = 0, length = elems.length, callbackExpect = !invert; // Go through the array, only saving the items // that pass the validator function for (; i < length; i++) { callbackInverse = !callback(elems[i], i); if (callbackInverse !== callbackExpect) { matches.push(elems[i]); } } return matches; }, // arg is for internal usage only map: function map(elems, callback, arg) { var length, value, i = 0, ret = []; // Go through the array, translating each of the items to their new values if (isArrayLike(elems)) { length = elems.length; for (; i < length; i++) { value = callback(elems[i], i, arg); if (value != null) { ret.push(value); } } // Go through every key on the object, } else { for (i in elems) { value = callback(elems[i], i, arg); if (value != null) { ret.push(value); } } } // Flatten any nested arrays return concat.apply([], ret); }, // A global GUID counter for objects guid: 1, // jQuery.support is not used in Core but other projects attach their // properties to it so it needs to exist. support: support }); if (typeof Symbol === "function") { jQuery.fn[Symbol.iterator] = arr[Symbol.iterator]; } // Populate the class2type map jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), function (i, name) { class2type["[object " + name + "]"] = name.toLowerCase(); }); function isArrayLike(obj) { // Support: real iOS 8.2 only (not reproducible in simulator) // `in` check used to prevent JIT error (gh-2145) // hasOwn isn't used here due to false negatives // regarding Nodelist length in IE var length = !!obj && "length" in obj && obj.length, type = toType(obj); if (isFunction(obj) || isWindow(obj)) { return false; } return type === "array" || length === 0 || typeof length === "number" && length > 0 && length - 1 in obj; } var Sizzle = /*! * Sizzle CSS Selector Engine v2.3.3 * https://sizzlejs.com/ * * Copyright jQuery Foundation and other contributors * Released under the MIT license * http://jquery.org/license * * Date: 2016-08-08 */ function (window) { var i, support, Expr, getText, isXML, tokenize, compile, select, outermostContext, sortInput, hasDuplicate, // Local document vars setDocument, document, docElem, documentIsHTML, rbuggyQSA, rbuggyMatches, matches, contains, // Instance-specific data expando = "sizzle" + 1 * new Date(), preferredDoc = window.document, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), sortOrder = function sortOrder(a, b) { if (a === b) { hasDuplicate = true; } return 0; }, // Instance methods hasOwn = {}.hasOwnProperty, arr = [], pop = arr.pop, push_native = arr.push, push = arr.push, slice = arr.slice, // Use a stripped-down indexOf as it's faster than native // https://jsperf.com/thor-indexof-vs-for/5 indexOf = function indexOf(list, elem) { var i = 0, len = list.length; for (; i < len; i++) { if (list[i] === elem) { return i; } } return -1; }, booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", // Regular expressions // http://www.w3.org/TR/css3-selectors/#whitespace whitespace = "[\\x20\\t\\r\\n\\f]", // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2) "*([*^$|!~]?=)" + whitespace + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]", pseudos = ":(" + identifier + ")(?:\\((" + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: // 1. quoted (capture 3; capture 4 or capture 5) "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + // 2. simple (capture 6) "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + // 3. anything else (capture 2) ".*" + ")\\)|)", // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter rwhitespace = new RegExp(whitespace + "+", "g"), rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g"), rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"), rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"), rattributeQuotes = new RegExp("=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g"), rpseudo = new RegExp(pseudos), ridentifier = new RegExp("^" + identifier + "$"), matchExpr = { "ID": new RegExp("^#(" + identifier + ")"), "CLASS": new RegExp("^\\.(" + identifier + ")"), "TAG": new RegExp("^(" + identifier + "|[*])"), "ATTR": new RegExp("^" + attributes), "PSEUDO": new RegExp("^" + pseudos), "CHILD": new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i"), "bool": new RegExp("^(?:" + booleans + ")$", "i"), // For use in libraries implementing .is() // We use this for POS matching in `select` "needsContext": new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i") }, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rnative = /^[^{]+\{\s*\[native \w/, // Easily-parseable/retrievable ID or TAG or CLASS selectors rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, // CSS escapes // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters runescape = new RegExp("\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig"), funescape = function funescape(_, escaped, escapedWhitespace) { var high = "0x" + escaped - 0x10000; // NaN means non-codepoint // Support: Firefox<24 // Workaround erroneous numeric interpretation of +"0x" return high !== high || escapedWhitespace ? escaped : high < 0 ? // BMP codepoint String.fromCharCode(high + 0x10000) : // Supplemental Plane codepoint (surrogate pair) String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00); }, // CSS string/identifier serialization // https://drafts.csswg.org/cssom/#common-serializing-idioms rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, fcssescape = function fcssescape(ch, asCodePoint) { if (asCodePoint) { // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER if (ch === "\0") { return "\uFFFD"; } // Control characters and (dependent upon position) numbers get escaped as code points return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " "; } // Other potentially-special ASCII characters get backslash-escaped return "\\" + ch; }, // Used for iframes // See setDocument() // Removing the function wrapper causes a "Permission Denied" // error in IE unloadHandler = function unloadHandler() { setDocument(); }, disabledAncestor = addCombinator(function (elem) { return elem.disabled === true && ("form" in elem || "label" in elem); }, { dir: "parentNode", next: "legend" }); // Optimize for push.apply( _, NodeList ) try { push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes); // Support: Android<4.0 // Detect silently failing push.apply arr[preferredDoc.childNodes.length].nodeType; } catch (e) { push = { apply: arr.length ? // Leverage slice if possible function (target, els) { push_native.apply(target, slice.call(els)); } : // Support: IE<9 // Otherwise append directly function (target, els) { var j = target.length, i = 0; // Can't trust NodeList.length while (target[j++] = els[i++]) {} target.length = j - 1; } }; } function Sizzle(selector, context, results, seed) { var m, i, elem, nid, match, groups, newSelector, newContext = context && context.ownerDocument, // nodeType defaults to 9, since context defaults to document nodeType = context ? context.nodeType : 9; results = results || []; // Return early from calls with invalid selector or context if (typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11) { return results; } // Try to shortcut find operations (as opposed to filters) in HTML documents if (!seed) { if ((context ? context.ownerDocument || context : preferredDoc) !== document) { setDocument(context); } context = context || document; if (documentIsHTML) { // If the selector is sufficiently simple, try using a "get*By*" DOM method // (excepting DocumentFragment context, where the methods don't exist) if (nodeType !== 11 && (match = rquickExpr.exec(selector))) { // ID selector if (m = match[1]) { // Document context if (nodeType === 9) { if (elem = context.getElementById(m)) { // Support: IE, Opera, Webkit // TODO: identify versions // getElementById can match elements by name instead of ID if (elem.id === m) { results.push(elem); return results; } } else { return results; } // Element context } else { // Support: IE, Opera, Webkit // TODO: identify versions // getElementById can match elements by name instead of ID if (newContext && (elem = newContext.getElementById(m)) && contains(context, elem) && elem.id === m) { results.push(elem); return results; } } // Type selector } else if (match[2]) { push.apply(results, context.getElementsByTagName(selector)); return results; // Class selector } else if ((m = match[3]) && support.getElementsByClassName && context.getElementsByClassName) { push.apply(results, context.getElementsByClassName(m)); return results; } } // Take advantage of querySelectorAll if (support.qsa && !compilerCache[selector + " "] && (!rbuggyQSA || !rbuggyQSA.test(selector))) { if (nodeType !== 1) { newContext = context; newSelector = selector; // qSA looks outside Element context, which is not what we want // Thanks to Andrew Dupont for this workaround technique // Support: IE <=8 // Exclude object elements } else if (context.nodeName.toLowerCase() !== "object") { // Capture the context ID, setting it first if necessary if (nid = context.getAttribute("id")) { nid = nid.replace(rcssescape, fcssescape); } else { context.setAttribute("id", nid = expando); } // Prefix every selector in the list groups = tokenize(selector); i = groups.length; while (i--) { groups[i] = "#" + nid + " " + toSelector(groups[i]); } newSelector = groups.join(","); // Expand context for sibling selectors newContext = rsibling.test(selector) && testContext(context.parentNode) || context; } if (newSelector) { try { push.apply(results, newContext.querySelectorAll(newSelector)); return results; } catch (qsaError) {} finally { if (nid === expando) { context.removeAttribute("id"); } } } } } } // All others return select(selector.replace(rtrim, "$1"), context, results, seed); } /** * Create key-value caches of limited size * @returns {function(string, object)} Returns the Object data after storing it on itself with * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) * deleting the oldest entry */ function createCache() { var keys = []; function cache(key, value) { // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) if (keys.push(key + " ") > Expr.cacheLength) { // Only keep the most recent entries delete cache[keys.shift()]; } return cache[key + " "] = value; } return cache; } /** * Mark a function for special use by Sizzle * @param {Function} fn The function to mark */ function markFunction(fn) { fn[expando] = true; return fn; } /** * Support testing using an element * @param {Function} fn Passed the created element and returns a boolean result */ function assert(fn) { var el = document.createElement("fieldset"); try { return !!fn(el); } catch (e) { return false; } finally { // Remove from its parent by default if (el.parentNode) { el.parentNode.removeChild(el); } // release memory in IE el = null; } } /** * Adds the same handler for all of the specified attrs * @param {String} attrs Pipe-separated list of attributes * @param {Function} handler The method that will be applied */ function addHandle(attrs, handler) { var arr = attrs.split("|"), i = arr.length; while (i--) { Expr.attrHandle[arr[i]] = handler; } } /** * Checks document order of two siblings * @param {Element} a * @param {Element} b * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b */ function siblingCheck(a, b) { var cur = b && a, diff = cur && a.nodeType === 1 && b.nodeType === 1 && a.sourceIndex - b.sourceIndex; // Use IE sourceIndex if available on both nodes if (diff) { return diff; } // Check if b follows a if (cur) { while (cur = cur.nextSibling) { if (cur === b) { return -1; } } } return a ? 1 : -1; } /** * Returns a function to use in pseudos for input types * @param {String} type */ function createInputPseudo(type) { return function (elem) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === type; }; } /** * Returns a function to use in pseudos for buttons * @param {String} type */ function createButtonPseudo(type) { return function (elem) { var name = elem.nodeName.toLowerCase(); return (name === "input" || name === "button") && elem.type === type; }; } /** * Returns a function to use in pseudos for :enabled/:disabled * @param {Boolean} disabled true for :disabled; false for :enabled */ function createDisabledPseudo(disabled) { // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable return function (elem) { // Only certain elements can match :enabled or :disabled // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled if ("form" in elem) { // Check for inherited disabledness on relevant non-disabled elements: // * listed form-associated elements in a disabled fieldset // https://html.spec.whatwg.org/multipage/forms.html#category-listed // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled // * option elements in a disabled optgroup // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled // All such elements have a "form" property. if (elem.parentNode && elem.disabled === false) { // Option elements defer to a parent optgroup if present if ("label" in elem) { if ("label" in elem.parentNode) { return elem.parentNode.disabled === disabled; } else { return elem.disabled === disabled; } } // Support: IE 6 - 11 // Use the isDisabled shortcut property to check for disabled fieldset ancestors return elem.isDisabled === disabled || // Where there is no isDisabled, check manually /* jshint -W018 */ elem.isDisabled !== !disabled && disabledAncestor(elem) === disabled; } return elem.disabled === disabled; // Try to winnow out elements that can't be disabled before trusting the disabled property. // Some victims get caught in our net (label, legend, menu, track), but it shouldn't // even exist on them, let alone have a boolean value. } else if ("label" in elem) { return elem.disabled === disabled; } // Remaining elements are neither :enabled nor :disabled return false; }; } /** * Returns a function to use in pseudos for positionals * @param {Function} fn */ function createPositionalPseudo(fn) { return markFunction(function (argument) { argument = +argument; return markFunction(function (seed, matches) { var j, matchIndexes = fn([], seed.length, argument), i = matchIndexes.length; // Match elements found at the specified indexes while (i--) { if (seed[j = matchIndexes[i]]) { seed[j] = !(matches[j] = seed[j]); } } }); }); } /** * Checks a node for validity as a Sizzle context * @param {Element|Object=} context * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value */ function testContext(context) { return context && typeof context.getElementsByTagName !== "undefined" && context; } // Expose support vars for convenience support = Sizzle.support = {}; /** * Detects XML nodes * @param {Element|Object} elem An element or a document * @returns {Boolean} True iff elem is a non-HTML XML node */ isXML = Sizzle.isXML = function (elem) { // documentElement is verified for cases where it doesn't yet exist // (such as loading iframes in IE - #4833) var documentElement = elem && (elem.ownerDocument || elem).documentElement; return documentElement ? documentElement.nodeName !== "HTML" : false; }; /** * Sets document-related variables once based on the current document * @param {Element|Object} [doc] An element or document object to use to set the document * @returns {Object} Returns the current document */ setDocument = Sizzle.setDocument = function (node) { var hasCompare, subWindow, doc = node ? node.ownerDocument || node : preferredDoc; // Return early if doc is invalid or already selected if (doc === document || doc.nodeType !== 9 || !doc.documentElement) { return document; } // Update global variables document = doc; docElem = document.documentElement; documentIsHTML = !isXML(document); // Support: IE 9-11, Edge // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) if (preferredDoc !== document && (subWindow = document.defaultView) && subWindow.top !== subWindow) { // Support: IE 11, Edge if (subWindow.addEventListener) { subWindow.addEventListener("unload", unloadHandler, false); // Support: IE 9 - 10 only } else if (subWindow.attachEvent) { subWindow.attachEvent("onunload", unloadHandler); } } /* Attributes ---------------------------------------------------------------------- */ // Support: IE<8 // Verify that getAttribute really returns attributes and not properties // (excepting IE8 booleans) support.attributes = assert(function (el) { el.className = "i"; return !el.getAttribute("className"); }); /* getElement(s)By* ---------------------------------------------------------------------- */ // Check if getElementsByTagName("*") returns only elements support.getElementsByTagName = assert(function (el) { el.appendChild(document.createComment("")); return !el.getElementsByTagName("*").length; }); // Support: IE<9 support.getElementsByClassName = rnative.test(document.getElementsByClassName); // Support: IE<10 // Check if getElementById returns elements by name // The broken getElementById methods don't pick up programmatically-set names, // so use a roundabout getElementsByName test support.getById = assert(function (el) { docElem.appendChild(el).id = expando; return !document.getElementsByName || !document.getElementsByName(expando).length; }); // ID filter and find if (support.getById) { Expr.filter["ID"] = function (id) { var attrId = id.replace(runescape, funescape); return function (elem) { return elem.getAttribute("id") === attrId; }; }; Expr.find["ID"] = function (id, context) { if (typeof context.getElementById !== "undefined" && documentIsHTML) { var elem = context.getElementById(id); return elem ? [elem] : []; } }; } else { Expr.filter["ID"] = function (id) { var attrId = id.replace(runescape, funescape); return function (elem) { var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); return node && node.value === attrId; }; }; // Support: IE 6 - 7 only // getElementById is not reliable as a find shortcut Expr.find["ID"] = function (id, context) { if (typeof context.getElementById !== "undefined" && documentIsHTML) { var node, i, elems, elem = context.getElementById(id); if (elem) { // Verify the id attribute node = elem.getAttributeNode("id"); if (node && node.value === id) { return [elem]; } // Fall back on getElementsByName elems = context.getElementsByName(id); i = 0; while (elem = elems[i++]) { node = elem.getAttributeNode("id"); if (node && node.value === id) { return [elem]; } } } return []; } }; } // Tag Expr.find["TAG"] = support.getElementsByTagName ? function (tag, context) { if (typeof context.getElementsByTagName !== "undefined") { return context.getElementsByTagName(tag); // DocumentFragment nodes don't have gEBTN } else if (support.qsa) { return context.querySelectorAll(tag); } } : function (tag, context) { var elem, tmp = [], i = 0, // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too results = context.getElementsByTagName(tag); // Filter out possible comments if (tag === "*") { while (elem = results[i++]) { if (elem.nodeType === 1) { tmp.push(elem); } } return tmp; } return results; }; // Class Expr.find["CLASS"] = support.getElementsByClassName && function (className, context) { if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) { return context.getElementsByClassName(className); } }; /* QSA/matchesSelector ---------------------------------------------------------------------- */ // QSA and matchesSelector support // matchesSelector(:active) reports false when true (IE9/Opera 11.5) rbuggyMatches = []; // qSa(:focus) reports false when true (Chrome 21) // We allow this because of a bug in IE8/9 that throws an error // whenever `document.activeElement` is accessed on an iframe // So, we allow :focus to pass through QSA all the time to avoid the IE error // See https://bugs.jquery.com/ticket/13378 rbuggyQSA = []; if (support.qsa = rnative.test(document.querySelectorAll)) { // Build QSA regex // Regex strategy adopted from Diego Perini assert(function (el) { // Select is set to empty string on purpose // This is to test IE's treatment of not explicitly // setting a boolean content attribute, // since its presence should be enough // https://bugs.jquery.com/ticket/12359 docElem.appendChild(el).innerHTML = "" + ""; // Support: IE8, Opera 11-12.16 // Nothing should be selected when empty strings follow ^= or $= or *= // The test attribute must be unknown in Opera but "safe" for WinRT // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section if (el.querySelectorAll("[msallowcapture^='']").length) { rbuggyQSA.push("[*^$]=" + whitespace + "*(?:''|\"\")"); } // Support: IE8 // Boolean attributes and "value" are not treated correctly if (!el.querySelectorAll("[selected]").length) { rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")"); } // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ if (!el.querySelectorAll("[id~=" + expando + "-]").length) { rbuggyQSA.push("~="); } // Webkit/Opera - :checked should return selected option elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked // IE8 throws error here and will not see later tests if (!el.querySelectorAll(":checked").length) { rbuggyQSA.push(":checked"); } // Support: Safari 8+, iOS 8+ // https://bugs.webkit.org/show_bug.cgi?id=136851 // In-page `selector#id sibling-combinator selector` fails if (!el.querySelectorAll("a#" + expando + "+*").length) { rbuggyQSA.push(".#.+[+~]"); } }); assert(function (el) { el.innerHTML = "" + ""; // Support: Windows 8 Native Apps // The type and name attributes are restricted during .innerHTML assignment var input = document.createElement("input"); input.setAttribute("type", "hidden"); el.appendChild(input).setAttribute("name", "D"); // Support: IE8 // Enforce case-sensitivity of name attribute if (el.querySelectorAll("[name=d]").length) { rbuggyQSA.push("name" + whitespace + "*[*^$|!~]?="); } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) // IE8 throws error here and will not see later tests if (el.querySelectorAll(":enabled").length !== 2) { rbuggyQSA.push(":enabled", ":disabled"); } // Support: IE9-11+ // IE's :disabled selector does not pick up the children of disabled fieldsets docElem.appendChild(el).disabled = true; if (el.querySelectorAll(":disabled").length !== 2) { rbuggyQSA.push(":enabled", ":disabled"); } // Opera 10-11 does not throw on post-comma invalid pseudos el.querySelectorAll("*,:x"); rbuggyQSA.push(",.*:"); }); } if (support.matchesSelector = rnative.test(matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector)) { assert(function (el) { // Check to see if it's possible to do matchesSelector // on a disconnected node (IE 9) support.disconnectedMatch = matches.call(el, "*"); // This should fail with an exception // Gecko does not error, returns false instead matches.call(el, "[s!='']:x"); rbuggyMatches.push("!=", pseudos); }); } rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|")); rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|")); /* Contains ---------------------------------------------------------------------- */ hasCompare = rnative.test(docElem.compareDocumentPosition); // Element contains another // Purposefully self-exclusive // As in, an element does not contain itself contains = hasCompare || rnative.test(docElem.contains) ? function (a, b) { var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode; return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16)); } : function (a, b) { if (b) { while (b = b.parentNode) { if (b === a) { return true; } } } return false; }; /* Sorting ---------------------------------------------------------------------- */ // Document order sorting sortOrder = hasCompare ? function (a, b) { // Flag for duplicate removal if (a === b) { hasDuplicate = true; return 0; } // Sort on method existence if only one input has compareDocumentPosition var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; if (compare) { return compare; } // Calculate position if both inputs belong to the same document compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : // Otherwise we know they are disconnected 1; // Disconnected nodes if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) { // Choose the first element that is related to our preferred document if (a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) { return -1; } if (b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) { return 1; } // Maintain original order return sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0; } return compare & 4 ? -1 : 1; } : function (a, b) { // Exit early if the nodes are identical if (a === b) { hasDuplicate = true; return 0; } var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [a], bp = [b]; // Parentless nodes are either documents or disconnected if (!aup || !bup) { return a === document ? -1 : b === document ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0; // If the nodes are siblings, we can do a quick check } else if (aup === bup) { return siblingCheck(a, b); } // Otherwise we need full lists of their ancestors for comparison cur = a; while (cur = cur.parentNode) { ap.unshift(cur); } cur = b; while (cur = cur.parentNode) { bp.unshift(cur); } // Walk down the tree looking for a discrepancy while (ap[i] === bp[i]) { i++; } return i ? // Do a sibling check if the nodes have a common ancestor siblingCheck(ap[i], bp[i]) : // Otherwise nodes in our document sort first ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0; }; return document; }; Sizzle.matches = function (expr, elements) { return Sizzle(expr, null, null, elements); }; Sizzle.matchesSelector = function (elem, expr) { // Set document vars if needed if ((elem.ownerDocument || elem) !== document) { setDocument(elem); } // Make sure that attribute selectors are quoted expr = expr.replace(rattributeQuotes, "='$1']"); if (support.matchesSelector && documentIsHTML && !compilerCache[expr + " "] && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) { try { var ret = matches.call(elem, expr); // IE 9's matchesSelector returns false on disconnected nodes if (ret || support.disconnectedMatch || // As well, disconnected nodes are said to be in a document // fragment in IE 9 elem.document && elem.document.nodeType !== 11) { return ret; } } catch (e) {} } return Sizzle(expr, document, null, [elem]).length > 0; }; Sizzle.contains = function (context, elem) { // Set document vars if needed if ((context.ownerDocument || context) !== document) { setDocument(context); } return contains(context, elem); }; Sizzle.attr = function (elem, name) { // Set document vars if needed if ((elem.ownerDocument || elem) !== document) { setDocument(elem); } var fn = Expr.attrHandle[name.toLowerCase()], // Don't get fooled by Object.prototype properties (jQuery #13807) val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined; return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; }; Sizzle.escape = function (sel) { return (sel + "").replace(rcssescape, fcssescape); }; Sizzle.error = function (msg) { throw new Error("Syntax error, unrecognized expression: " + msg); }; /** * Document sorting and removing duplicates * @param {ArrayLike} results */ Sizzle.uniqueSort = function (results) { var elem, duplicates = [], j = 0, i = 0; // Unless we *know* we can detect duplicates, assume their presence hasDuplicate = !support.detectDuplicates; sortInput = !support.sortStable && results.slice(0); results.sort(sortOrder); if (hasDuplicate) { while (elem = results[i++]) { if (elem === results[i]) { j = duplicates.push(i); } } while (j--) { results.splice(duplicates[j], 1); } } // Clear input after sorting to release objects // See https://github.com/jquery/sizzle/pull/225 sortInput = null; return results; }; /** * Utility function for retrieving the text value of an array of DOM nodes * @param {Array|Element} elem */ getText = Sizzle.getText = function (elem) { var node, ret = "", i = 0, nodeType = elem.nodeType; if (!nodeType) { // If no nodeType, this is expected to be an array while (node = elem[i++]) { // Do not traverse comment nodes ret += getText(node); } } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) { // Use textContent for elements // innerText usage removed for consistency of new lines (jQuery #11153) if (typeof elem.textContent === "string") { return elem.textContent; } else { // Traverse its children for (elem = elem.firstChild; elem; elem = elem.nextSibling) { ret += getText(elem); } } } else if (nodeType === 3 || nodeType === 4) { return elem.nodeValue; } // Do not include comment or processing instruction nodes return ret; }; Expr = Sizzle.selectors = { // Can be adjusted by the user cacheLength: 50, createPseudo: markFunction, match: matchExpr, attrHandle: {}, find: {}, relative: { ">": { dir: "parentNode", first: true }, " ": { dir: "parentNode" }, "+": { dir: "previousSibling", first: true }, "~": { dir: "previousSibling" } }, preFilter: { "ATTR": function ATTR(match) { match[1] = match[1].replace(runescape, funescape); // Move the given value to match[3] whether quoted or unquoted match[3] = (match[3] || match[4] || match[5] || "").replace(runescape, funescape); if (match[2] === "~=") { match[3] = " " + match[3] + " "; } return match.slice(0, 4); }, "CHILD": function CHILD(match) { /* matches from matchExpr["CHILD"] 1 type (only|nth|...) 2 what (child|of-type) 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 4 xn-component of xn+y argument ([+-]?\d*n|) 5 sign of xn-component 6 x of xn-component 7 sign of y-component 8 y of y-component */ match[1] = match[1].toLowerCase(); if (match[1].slice(0, 3) === "nth") { // nth-* requires argument if (!match[3]) { Sizzle.error(match[0]); } // numeric x and y parameters for Expr.filter.CHILD // remember that false/true cast respectively to 0/1 match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd")); match[5] = +(match[7] + match[8] || match[3] === "odd"); // other types prohibit arguments } else if (match[3]) { Sizzle.error(match[0]); } return match; }, "PSEUDO": function PSEUDO(match) { var excess, unquoted = !match[6] && match[2]; if (matchExpr["CHILD"].test(match[0])) { return null; } // Accept quoted arguments as-is if (match[3]) { match[2] = match[4] || match[5] || ""; // Strip excess characters from unquoted arguments } else if (unquoted && rpseudo.test(unquoted) && ( // Get excess from tokenize (recursively) excess = tokenize(unquoted, true)) && ( // advance to the next closing parenthesis excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) { // excess is a negative index match[0] = match[0].slice(0, excess); match[2] = unquoted.slice(0, excess); } // Return only captures needed by the pseudo filter method (type and argument) return match.slice(0, 3); } }, filter: { "TAG": function TAG(nodeNameSelector) { var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase(); return nodeNameSelector === "*" ? function () { return true; } : function (elem) { return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; }; }, "CLASS": function CLASS(className) { var pattern = classCache[className + " "]; return pattern || (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) && classCache(className, function (elem) { return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || ""); }); }, "ATTR": function ATTR(name, operator, check) { return function (elem) { var result = Sizzle.attr(elem, name); if (result == null) { return operator === "!="; } if (!operator) { return true; } result += ""; return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf(check) === 0 : operator === "*=" ? check && result.indexOf(check) > -1 : operator === "$=" ? check && result.slice(-check.length) === check : operator === "~=" ? (" " + result.replace(rwhitespace, " ") + " ").indexOf(check) > -1 : operator === "|=" ? result === check || result.slice(0, check.length + 1) === check + "-" : false; }; }, "CHILD": function CHILD(type, what, argument, first, last) { var simple = type.slice(0, 3) !== "nth", forward = type.slice(-4) !== "last", ofType = what === "of-type"; return first === 1 && last === 0 ? // Shortcut for :nth-*(n) function (elem) { return !!elem.parentNode; } : function (elem, context, xml) { var cache, uniqueCache, outerCache, node, nodeIndex, start, dir = simple !== forward ? "nextSibling" : "previousSibling", parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType, diff = false; if (parent) { // :(first|last|only)-(child|of-type) if (simple) { while (dir) { node = elem; while (node = node[dir]) { if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) { return false; } } // Reverse direction for :only-* (if we haven't yet done so) start = dir = type === "only" && !start && "nextSibling"; } return true; } start = [forward ? parent.firstChild : parent.lastChild]; // non-xml :nth-child(...) stores cache data on `parent` if (forward && useCache) { // Seek `elem` from a previously-cached index // ...in a gzip-friendly way node = parent; outerCache = node[expando] || (node[expando] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); cache = uniqueCache[type] || []; nodeIndex = cache[0] === dirruns && cache[1]; diff = nodeIndex && cache[2]; node = nodeIndex && parent.childNodes[nodeIndex]; while (node = ++nodeIndex && node && node[dir] || ( // Fallback to seeking `elem` from the start diff = nodeIndex = 0) || start.pop()) { // When found, cache indexes on `parent` and break if (node.nodeType === 1 && ++diff && node === elem) { uniqueCache[type] = [dirruns, nodeIndex, diff]; break; } } } else { // Use previously-cached element index if available if (useCache) { // ...in a gzip-friendly way node = elem; outerCache = node[expando] || (node[expando] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); cache = uniqueCache[type] || []; nodeIndex = cache[0] === dirruns && cache[1]; diff = nodeIndex; } // xml :nth-child(...) // or :nth-last-child(...) or :nth(-last)?-of-type(...) if (diff === false) { // Use the same loop as above to seek `elem` from the start while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) { if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) { // Cache the index of each encountered element if (useCache) { outerCache = node[expando] || (node[expando] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); uniqueCache[type] = [dirruns, diff]; } if (node === elem) { break; } } } } } // Incorporate the offset, then check against cycle size diff -= last; return diff === first || diff % first === 0 && diff / first >= 0; } }; }, "PSEUDO": function PSEUDO(pseudo, argument) { // pseudo-class names are case-insensitive // http://www.w3.org/TR/selectors/#pseudo-classes // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters // Remember that setFilters inherits from pseudos var args, fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error("unsupported pseudo: " + pseudo); // The user may use createPseudo to indicate that // arguments are needed to create the filter function // just as Sizzle does if (fn[expando]) { return fn(argument); } // But maintain support for old signatures if (fn.length > 1) { args = [pseudo, pseudo, "", argument]; return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) { var idx, matched = fn(seed, argument), i = matched.length; while (i--) { idx = indexOf(seed, matched[i]); seed[idx] = !(matches[idx] = matched[i]); } }) : function (elem) { return fn(elem, 0, args); }; } return fn; } }, pseudos: { // Potentially complex pseudos "not": markFunction(function (selector) { // Trim the selector passed to compile // to avoid treating leading and trailing // spaces as combinators var input = [], results = [], matcher = compile(selector.replace(rtrim, "$1")); return matcher[expando] ? markFunction(function (seed, matches, context, xml) { var elem, unmatched = matcher(seed, null, xml, []), i = seed.length; // Match elements unmatched by `matcher` while (i--) { if (elem = unmatched[i]) { seed[i] = !(matches[i] = elem); } } }) : function (elem, context, xml) { input[0] = elem; matcher(input, null, xml, results); // Don't keep the element (issue #299) input[0] = null; return !results.pop(); }; }), "has": markFunction(function (selector) { return function (elem) { return Sizzle(selector, elem).length > 0; }; }), "contains": markFunction(function (text) { text = text.replace(runescape, funescape); return function (elem) { return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1; }; }), // "Whether an element is represented by a :lang() selector // is based solely on the element's language value // being equal to the identifier C, // or beginning with the identifier C immediately followed by "-". // The matching of C against the element's language value is performed case-insensitively. // The identifier C does not have to be a valid language name." // http://www.w3.org/TR/selectors/#lang-pseudo "lang": markFunction(function (lang) { // lang value must be a valid identifier if (!ridentifier.test(lang || "")) { Sizzle.error("unsupported lang: " + lang); } lang = lang.replace(runescape, funescape).toLowerCase(); return function (elem) { var elemLang; do { if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute("xml:lang") || elem.getAttribute("lang")) { elemLang = elemLang.toLowerCase(); return elemLang === lang || elemLang.indexOf(lang + "-") === 0; } } while ((elem = elem.parentNode) && elem.nodeType === 1); return false; }; }), // Miscellaneous "target": function target(elem) { var hash = window.location && window.location.hash; return hash && hash.slice(1) === elem.id; }, "root": function root(elem) { return elem === docElem; }, "focus": function focus(elem) { return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); }, // Boolean properties "enabled": createDisabledPseudo(false), "disabled": createDisabledPseudo(true), "checked": function checked(elem) { // In CSS3, :checked should return both checked and selected elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked var nodeName = elem.nodeName.toLowerCase(); return nodeName === "input" && !!elem.checked || nodeName === "option" && !!elem.selected; }, "selected": function selected(elem) { // Accessing this property makes selected-by-default // options in Safari work properly if (elem.parentNode) { elem.parentNode.selectedIndex; } return elem.selected === true; }, // Contents "empty": function empty(elem) { // http://www.w3.org/TR/selectors/#empty-pseudo // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), // but not by others (comment: 8; processing instruction: 7; etc.) // nodeType < 6 works because attributes (2) do not appear as children for (elem = elem.firstChild; elem; elem = elem.nextSibling) { if (elem.nodeType < 6) { return false; } } return true; }, "parent": function parent(elem) { return !Expr.pseudos["empty"](elem); }, // Element/input types "header": function header(elem) { return rheader.test(elem.nodeName); }, "input": function input(elem) { return rinputs.test(elem.nodeName); }, "button": function button(elem) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === "button" || name === "button"; }, "text": function text(elem) { var attr; return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && ( // Support: IE<8 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text"); }, // Position-in-collection "first": createPositionalPseudo(function () { return [0]; }), "last": createPositionalPseudo(function (matchIndexes, length) { return [length - 1]; }), "eq": createPositionalPseudo(function (matchIndexes, length, argument) { return [argument < 0 ? argument + length : argument]; }), "even": createPositionalPseudo(function (matchIndexes, length) { var i = 0; for (; i < length; i += 2) { matchIndexes.push(i); } return matchIndexes; }), "odd": createPositionalPseudo(function (matchIndexes, length) { var i = 1; for (; i < length; i += 2) { matchIndexes.push(i); } return matchIndexes; }), "lt": createPositionalPseudo(function (matchIndexes, length, argument) { var i = argument < 0 ? argument + length : argument; for (; --i >= 0;) { matchIndexes.push(i); } return matchIndexes; }), "gt": createPositionalPseudo(function (matchIndexes, length, argument) { var i = argument < 0 ? argument + length : argument; for (; ++i < length;) { matchIndexes.push(i); } return matchIndexes; }) } }; Expr.pseudos["nth"] = Expr.pseudos["eq"]; // Add button/input type pseudos for (i in { radio: true, checkbox: true, file: true, password: true, image: true }) { Expr.pseudos[i] = createInputPseudo(i); } for (i in { submit: true, reset: true }) { Expr.pseudos[i] = createButtonPseudo(i); } // Easy API for creating new setFilters function setFilters() {} setFilters.prototype = Expr.filters = Expr.pseudos; Expr.setFilters = new setFilters(); tokenize = Sizzle.tokenize = function (selector, parseOnly) { var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[selector + " "]; if (cached) { return parseOnly ? 0 : cached.slice(0); } soFar = selector; groups = []; preFilters = Expr.preFilter; while (soFar) { // Comma and first run if (!matched || (match = rcomma.exec(soFar))) { if (match) { // Don't consume trailing commas as valid soFar = soFar.slice(match[0].length) || soFar; } groups.push(tokens = []); } matched = false; // Combinators if (match = rcombinators.exec(soFar)) { matched = match.shift(); tokens.push({ value: matched, // Cast descendant combinators to space type: match[0].replace(rtrim, " ") }); soFar = soFar.slice(matched.length); } // Filters for (type in Expr.filter) { if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) { matched = match.shift(); tokens.push({ value: matched, type: type, matches: match }); soFar = soFar.slice(matched.length); } } if (!matched) { break; } } // Return the length of the invalid excess // if we're just parsing // Otherwise, throw an error or return tokens return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) : // Cache the tokens tokenCache(selector, groups).slice(0); }; function toSelector(tokens) { var i = 0, len = tokens.length, selector = ""; for (; i < len; i++) { selector += tokens[i].value; } return selector; } function addCombinator(matcher, combinator, base) { var dir = combinator.dir, skip = combinator.next, key = skip || dir, checkNonElements = base && key === "parentNode", doneName = done++; return combinator.first ? // Check against closest ancestor/preceding element function (elem, context, xml) { while (elem = elem[dir]) { if (elem.nodeType === 1 || checkNonElements) { return matcher(elem, context, xml); } } return false; } : // Check against all ancestor/preceding elements function (elem, context, xml) { var oldCache, uniqueCache, outerCache, newCache = [dirruns, doneName]; // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching if (xml) { while (elem = elem[dir]) { if (elem.nodeType === 1 || checkNonElements) { if (matcher(elem, context, xml)) { return true; } } } } else { while (elem = elem[dir]) { if (elem.nodeType === 1 || checkNonElements) { outerCache = elem[expando] || (elem[expando] = {}); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[elem.uniqueID] || (outerCache[elem.uniqueID] = {}); if (skip && skip === elem.nodeName.toLowerCase()) { elem = elem[dir] || elem; } else if ((oldCache = uniqueCache[key]) && oldCache[0] === dirruns && oldCache[1] === doneName) { // Assign to newCache so results back-propagate to previous elements return newCache[2] = oldCache[2]; } else { // Reuse newcache so results back-propagate to previous elements uniqueCache[key] = newCache; // A match means we're done; a fail means we have to keep checking if (newCache[2] = matcher(elem, context, xml)) { return true; } } } } } return false; }; } function elementMatcher(matchers) { return matchers.length > 1 ? function (elem, context, xml) { var i = matchers.length; while (i--) { if (!matchers[i](elem, context, xml)) { return false; } } return true; } : matchers[0]; } function multipleContexts(selector, contexts, results) { var i = 0, len = contexts.length; for (; i < len; i++) { Sizzle(selector, contexts[i], results); } return results; } function condense(unmatched, map, filter, context, xml) { var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null; for (; i < len; i++) { if (elem = unmatched[i]) { if (!filter || filter(elem, context, xml)) { newUnmatched.push(elem); if (mapped) { map.push(i); } } } } return newUnmatched; } function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) { if (postFilter && !postFilter[expando]) { postFilter = setMatcher(postFilter); } if (postFinder && !postFinder[expando]) { postFinder = setMatcher(postFinder, postSelector); } return markFunction(function (seed, results, context, xml) { var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, // Get initial elements from seed or context elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []), // Prefilter to get matcher input, preserving a map for seed-results synchronization matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems, matcherOut = matcher ? // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, postFinder || (seed ? preFilter : preexisting || postFilter) ? // ...intermediate processing is necessary [] : // ...otherwise use results directly results : matcherIn; // Find primary matches if (matcher) { matcher(matcherIn, matcherOut, context, xml); } // Apply postFilter if (postFilter) { temp = condense(matcherOut, postMap); postFilter(temp, [], context, xml); // Un-match failing elements by moving them back to matcherIn i = temp.length; while (i--) { if (elem = temp[i]) { matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem); } } } if (seed) { if (postFinder || preFilter) { if (postFinder) { // Get the final matcherOut by condensing this intermediate into postFinder contexts temp = []; i = matcherOut.length; while (i--) { if (elem = matcherOut[i]) { // Restore matcherIn since elem is not yet a final match temp.push(matcherIn[i] = elem); } } postFinder(null, matcherOut = [], temp, xml); } // Move matched elements from seed to results to keep them synchronized i = matcherOut.length; while (i--) { if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) { seed[temp] = !(results[temp] = elem); } } } // Add elements to results, through postFinder if defined } else { matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut); if (postFinder) { postFinder(null, results, matcherOut, xml); } else { push.apply(results, matcherOut); } } }); } function matcherFromTokens(tokens) { var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[tokens[0].type], implicitRelative = leadingRelative || Expr.relative[" "], i = leadingRelative ? 1 : 0, // The foundational matcher ensures that elements are reachable from top-level context(s) matchContext = addCombinator(function (elem) { return elem === checkContext; }, implicitRelative, true), matchAnyContext = addCombinator(function (elem) { return indexOf(checkContext, elem) > -1; }, implicitRelative, true), matchers = [function (elem, context, xml) { var ret = !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml)); // Avoid hanging onto element (issue #299) checkContext = null; return ret; }]; for (; i < len; i++) { if (matcher = Expr.relative[tokens[i].type]) { matchers = [addCombinator(elementMatcher(matchers), matcher)]; } else { matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches); // Return special upon seeing a positional matcher if (matcher[expando]) { // Find the next relative operator (if any) for proper handling j = ++i; for (; j < len; j++) { if (Expr.relative[tokens[j].type]) { break; } } return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector( // If the preceding token was a descendant combinator, insert an implicit any-element `*` tokens.slice(0, i - 1).concat({ value: tokens[i - 2].type === " " ? "*" : "" })).replace(rtrim, "$1"), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens)); } matchers.push(matcher); } } return elementMatcher(matchers); } function matcherFromGroupMatchers(elementMatchers, setMatchers) { var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function superMatcher(seed, context, xml, results, outermost) { var elem, j, matcher, matchedCount = 0, i = "0", unmatched = seed && [], setMatched = [], contextBackup = outermostContext, // We must always have either seed elements or outermost context elems = seed || byElement && Expr.find["TAG"]("*", outermost), // Use integer dirruns iff this is the outermost matcher dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1, len = elems.length; if (outermost) { outermostContext = context === document || context || outermost; } // Add elements passing elementMatchers directly to results // Support: IE<9, Safari // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id for (; i !== len && (elem = elems[i]) != null; i++) { if (byElement && elem) { j = 0; if (!context && elem.ownerDocument !== document) { setDocument(elem); xml = !documentIsHTML; } while (matcher = elementMatchers[j++]) { if (matcher(elem, context || document, xml)) { results.push(elem); break; } } if (outermost) { dirruns = dirrunsUnique; } } // Track unmatched elements for set filters if (bySet) { // They will have gone through all possible matchers if (elem = !matcher && elem) { matchedCount--; } // Lengthen the array for every element, matched or not if (seed) { unmatched.push(elem); } } } // `i` is now the count of elements visited above, and adding it to `matchedCount` // makes the latter nonnegative. matchedCount += i; // Apply set filters to unmatched elements // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` // equals `i`), unless we didn't visit _any_ elements in the above loop because we have // no element matchers and no seed. // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that // case, which will result in a "00" `matchedCount` that differs from `i` but is also // numerically zero. if (bySet && i !== matchedCount) { j = 0; while (matcher = setMatchers[j++]) { matcher(unmatched, setMatched, context, xml); } if (seed) { // Reintegrate element matches to eliminate the need for sorting if (matchedCount > 0) { while (i--) { if (!(unmatched[i] || setMatched[i])) { setMatched[i] = pop.call(results); } } } // Discard index placeholder values to get only actual matches setMatched = condense(setMatched); } // Add matches to results push.apply(results, setMatched); // Seedless set matches succeeding multiple successful matchers stipulate sorting if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) { Sizzle.uniqueSort(results); } } // Override manipulation of globals by nested matchers if (outermost) { dirruns = dirrunsUnique; outermostContext = contextBackup; } return unmatched; }; return bySet ? markFunction(superMatcher) : superMatcher; } compile = Sizzle.compile = function (selector, match /* Internal Use Only */) { var i, setMatchers = [], elementMatchers = [], cached = compilerCache[selector + " "]; if (!cached) { // Generate a function of recursive functions that can be used to check each element if (!match) { match = tokenize(selector); } i = match.length; while (i--) { cached = matcherFromTokens(match[i]); if (cached[expando]) { setMatchers.push(cached); } else { elementMatchers.push(cached); } } // Cache the compiled function cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers)); // Save selector and tokenization cached.selector = selector; } return cached; }; /** * A low-level selection function that works with Sizzle's compiled * selector functions * @param {String|Function} selector A selector or a pre-compiled * selector function built with Sizzle.compile * @param {Element} context * @param {Array} [results] * @param {Array} [seed] A set of elements to match against */ select = Sizzle.select = function (selector, context, results, seed) { var i, tokens, token, type, find, compiled = typeof selector === "function" && selector, match = !seed && tokenize(selector = compiled.selector || selector); results = results || []; // Try to minimize operations if there is only one selector in the list and no seed // (the latter of which guarantees us context) if (match.length === 1) { // Reduce context if the leading compound selector is an ID tokens = match[0] = match[0].slice(0); if (tokens.length > 2 && (token = tokens[0]).type === "ID" && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) { context = (Expr.find["ID"](token.matches[0].replace(runescape, funescape), context) || [])[0]; if (!context) { return results; // Precompiled matchers will still verify ancestry, so step up a level } else if (compiled) { context = context.parentNode; } selector = selector.slice(tokens.shift().value.length); } // Fetch a seed set for right-to-left matching i = matchExpr["needsContext"].test(selector) ? 0 : tokens.length; while (i--) { token = tokens[i]; // Abort if we hit a combinator if (Expr.relative[type = token.type]) { break; } if (find = Expr.find[type]) { // Search, expanding context for leading sibling combinators if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testContext(context.parentNode) || context)) { // If seed is empty or no tokens remain, we can return early tokens.splice(i, 1); selector = seed.length && toSelector(tokens); if (!selector) { push.apply(results, seed); return results; } break; } } } } // Compile and execute a filtering function if one is not provided // Provide `match` to avoid retokenization if we modified the selector above (compiled || compile(selector, match))(seed, context, !documentIsHTML, results, !context || rsibling.test(selector) && testContext(context.parentNode) || context); return results; }; // One-time assignments // Sort stability support.sortStable = expando.split("").sort(sortOrder).join("") === expando; // Support: Chrome 14-35+ // Always assume duplicates if they aren't passed to the comparison function support.detectDuplicates = !!hasDuplicate; // Initialize against the default document setDocument(); // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) // Detached nodes confoundingly follow *each other* support.sortDetached = assert(function (el) { // Should return 1, but returns 4 (following) return el.compareDocumentPosition(document.createElement("fieldset")) & 1; }); // Support: IE<8 // Prevent attribute/property "interpolation" // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx if (!assert(function (el) { el.innerHTML = ""; return el.firstChild.getAttribute("href") === "#"; })) { addHandle("type|href|height|width", function (elem, name, isXML) { if (!isXML) { return elem.getAttribute(name, name.toLowerCase() === "type" ? 1 : 2); } }); } // Support: IE<9 // Use defaultValue in place of getAttribute("value") if (!support.attributes || !assert(function (el) { el.innerHTML = ""; el.firstChild.setAttribute("value", ""); return el.firstChild.getAttribute("value") === ""; })) { addHandle("value", function (elem, name, isXML) { if (!isXML && elem.nodeName.toLowerCase() === "input") { return elem.defaultValue; } }); } // Support: IE<9 // Use getAttributeNode to fetch booleans when getAttribute lies if (!assert(function (el) { return el.getAttribute("disabled") == null; })) { addHandle(booleans, function (elem, name, isXML) { var val; if (!isXML) { return elem[name] === true ? name.toLowerCase() : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; } }); } return Sizzle; }(window); jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; // Deprecated jQuery.expr[":"] = jQuery.expr.pseudos; jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; jQuery.text = Sizzle.getText; jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; jQuery.escapeSelector = Sizzle.escape; var dir = function dir(elem, _dir, until) { var matched = [], truncate = until !== undefined; while ((elem = elem[_dir]) && elem.nodeType !== 9) { if (elem.nodeType === 1) { if (truncate && jQuery(elem).is(until)) { break; } matched.push(elem); } } return matched; }; var _siblings = function _siblings(n, elem) { var matched = []; for (; n; n = n.nextSibling) { if (n.nodeType === 1 && n !== elem) { matched.push(n); } } return matched; }; var rneedsContext = jQuery.expr.match.needsContext; function nodeName(elem, name) { return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); }; var rsingleTag = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i; // Implement the identical functionality for filter and not function winnow(elements, qualifier, not) { if (isFunction(qualifier)) { return jQuery.grep(elements, function (elem, i) { return !!qualifier.call(elem, i, elem) !== not; }); } // Single element if (qualifier.nodeType) { return jQuery.grep(elements, function (elem) { return elem === qualifier !== not; }); } // Arraylike of elements (jQuery, arguments, Array) if (typeof qualifier !== "string") { return jQuery.grep(elements, function (elem) { return indexOf.call(qualifier, elem) > -1 !== not; }); } // Filtered directly for both simple and complex selectors return jQuery.filter(qualifier, elements, not); } jQuery.filter = function (expr, elems, not) { var elem = elems[0]; if (not) { expr = ":not(" + expr + ")"; } if (elems.length === 1 && elem.nodeType === 1) { return jQuery.find.matchesSelector(elem, expr) ? [elem] : []; } return jQuery.find.matches(expr, jQuery.grep(elems, function (elem) { return elem.nodeType === 1; })); }; jQuery.fn.extend({ find: function find(selector) { var i, ret, len = this.length, self = this; if (typeof selector !== "string") { return this.pushStack(jQuery(selector).filter(function () { for (i = 0; i < len; i++) { if (jQuery.contains(self[i], this)) { return true; } } })); } ret = this.pushStack([]); for (i = 0; i < len; i++) { jQuery.find(selector, self[i], ret); } return len > 1 ? jQuery.uniqueSort(ret) : ret; }, filter: function filter(selector) { return this.pushStack(winnow(this, selector || [], false)); }, not: function not(selector) { return this.pushStack(winnow(this, selector || [], true)); }, is: function is(selector) { return !!winnow(this, // If this is a positional/relative selector, check membership in the returned set // so $("p:first").is("p:last") won't return true for a doc with two "p". typeof selector === "string" && rneedsContext.test(selector) ? jQuery(selector) : selector || [], false).length; } }); // Initialize a jQuery object // A central reference to the root jQuery(document) var rootjQuery, // A simple way to check for HTML strings // Prioritize #id over to avoid XSS via location.hash (#9521) // Strict HTML recognition (#11290: must start with <) // Shortcut simple #id case for speed rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, init = jQuery.fn.init = function (selector, context, root) { var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false) if (!selector) { return this; } // Method init() accepts an alternate rootjQuery // so migrate can support jQuery.sub (gh-2101) root = root || rootjQuery; // Handle HTML strings if (typeof selector === "string") { if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [null, selector, null]; } else { match = rquickExpr.exec(selector); } // Match html or make sure no context is specified for #id if (match && (match[1] || !context)) { // HANDLE: $(html) -> $(array) if (match[1]) { context = context instanceof jQuery ? context[0] : context; // Option to run scripts is true for back-compat // Intentionally let the error be thrown if parseHTML is not present jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document, true)); // HANDLE: $(html, props) if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) { for (match in context) { // Properties of context are called as methods if possible if (isFunction(this[match])) { this[match](context[match]); // ...and otherwise set as attributes } else { this.attr(match, context[match]); } } } return this; // HANDLE: $(#id) } else { elem = document.getElementById(match[2]); if (elem) { // Inject the element directly into the jQuery object this[0] = elem; this.length = 1; } return this; } // HANDLE: $(expr, $(...)) } else if (!context || context.jquery) { return (context || root).find(selector); // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { return this.constructor(context).find(selector); } // HANDLE: $(DOMElement) } else if (selector.nodeType) { this[0] = selector; this.length = 1; return this; // HANDLE: $(function) // Shortcut for document ready } else if (isFunction(selector)) { return root.ready !== undefined ? root.ready(selector) : // Execute immediately if ready is not present selector(jQuery); } return jQuery.makeArray(selector, this); }; // Give the init function the jQuery prototype for later instantiation init.prototype = jQuery.fn; // Initialize central reference rootjQuery = jQuery(document); var rparentsprev = /^(?:parents|prev(?:Until|All))/, // Methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, contents: true, next: true, prev: true }; jQuery.fn.extend({ has: function has(target) { var targets = jQuery(target, this), l = targets.length; return this.filter(function () { var i = 0; for (; i < l; i++) { if (jQuery.contains(this, targets[i])) { return true; } } }); }, closest: function closest(selectors, context) { var cur, i = 0, l = this.length, matched = [], targets = typeof selectors !== "string" && jQuery(selectors); // Positional selectors never match, since there's no _selection_ context if (!rneedsContext.test(selectors)) { for (; i < l; i++) { for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) { // Always skip document fragments if (cur.nodeType < 11 && (targets ? targets.index(cur) > -1 : // Don't pass non-elements to Sizzle cur.nodeType === 1 && jQuery.find.matchesSelector(cur, selectors))) { matched.push(cur); break; } } } } return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched); }, // Determine the position of an element within the set index: function index(elem) { // No argument, return index in parent if (!elem) { return this[0] && this[0].parentNode ? this.first().prevAll().length : -1; } // Index in selector if (typeof elem === "string") { return indexOf.call(jQuery(elem), this[0]); } // Locate the position of the desired element return indexOf.call(this, // If it receives a jQuery object, the first element is used elem.jquery ? elem[0] : elem); }, add: function add(selector, context) { return this.pushStack(jQuery.uniqueSort(jQuery.merge(this.get(), jQuery(selector, context)))); }, addBack: function addBack(selector) { return this.add(selector == null ? this.prevObject : this.prevObject.filter(selector)); } }); function sibling(cur, dir) { while ((cur = cur[dir]) && cur.nodeType !== 1) {} return cur; } jQuery.each({ parent: function parent(elem) { var parent = elem.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }, parents: function parents(elem) { return dir(elem, "parentNode"); }, parentsUntil: function parentsUntil(elem, i, until) { return dir(elem, "parentNode", until); }, next: function next(elem) { return sibling(elem, "nextSibling"); }, prev: function prev(elem) { return sibling(elem, "previousSibling"); }, nextAll: function nextAll(elem) { return dir(elem, "nextSibling"); }, prevAll: function prevAll(elem) { return dir(elem, "previousSibling"); }, nextUntil: function nextUntil(elem, i, until) { return dir(elem, "nextSibling", until); }, prevUntil: function prevUntil(elem, i, until) { return dir(elem, "previousSibling", until); }, siblings: function siblings(elem) { return _siblings((elem.parentNode || {}).firstChild, elem); }, children: function children(elem) { return _siblings(elem.firstChild); }, contents: function contents(elem) { if (nodeName(elem, "iframe")) { return elem.contentDocument; } // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only // Treat the template element as a regular one in browsers that // don't support it. if (nodeName(elem, "template")) { elem = elem.content || elem; } return jQuery.merge([], elem.childNodes); } }, function (name, fn) { jQuery.fn[name] = function (until, selector) { var matched = jQuery.map(this, fn, until); if (name.slice(-5) !== "Until") { selector = until; } if (selector && typeof selector === "string") { matched = jQuery.filter(selector, matched); } if (this.length > 1) { // Remove duplicates if (!guaranteedUnique[name]) { jQuery.uniqueSort(matched); } // Reverse order for parents* and prev-derivatives if (rparentsprev.test(name)) { matched.reverse(); } } return this.pushStack(matched); }; }); var rnothtmlwhite = /[^\x20\t\r\n\f]+/g; // Convert String-formatted options into Object-formatted ones function createOptions(options) { var object = {}; jQuery.each(options.match(rnothtmlwhite) || [], function (_, flag) { object[flag] = true; }); return object; } /* * Create a callback list using the following parameters: * * options: an optional list of space-separated options that will change how * the callback list behaves or a more traditional option object * * By default a callback list will act like an event callback list and can be * "fired" multiple times. * * Possible options: * * once: will ensure the callback list can only be fired once (like a Deferred) * * memory: will keep track of previous values and will call any callback added * after the list has been fired right away with the latest "memorized" * values (like a Deferred) * * unique: will ensure a callback can only be added once (no duplicate in the list) * * stopOnFalse: interrupt callings when a callback returns false * */ jQuery.Callbacks = function (options) { // Convert options from String-formatted to Object-formatted if needed // (we check in cache first) options = typeof options === "string" ? createOptions(options) : jQuery.extend({}, options); var // Flag to know if list is currently firing firing, // Last fire value for non-forgettable lists memory, // Flag to know if list was already fired _fired, // Flag to prevent firing _locked, // Actual callback list list = [], // Queue of execution data for repeatable lists queue = [], // Index of currently firing callback (modified by add/remove as needed) firingIndex = -1, // Fire callbacks fire = function fire() { // Enforce single-firing _locked = _locked || options.once; // Execute callbacks for all pending executions, // respecting firingIndex overrides and runtime changes _fired = firing = true; for (; queue.length; firingIndex = -1) { memory = queue.shift(); while (++firingIndex < list.length) { // Run callback and check for early termination if (list[firingIndex].apply(memory[0], memory[1]) === false && options.stopOnFalse) { // Jump to end and forget the data so .add doesn't re-fire firingIndex = list.length; memory = false; } } } // Forget the data if we're done with it if (!options.memory) { memory = false; } firing = false; // Clean up if we're done firing for good if (_locked) { // Keep an empty list if we have data for future add calls if (memory) { list = []; // Otherwise, this object is spent } else { list = ""; } } }, // Actual Callbacks object self = { // Add a callback or a collection of callbacks to the list add: function add() { if (list) { // If we have memory from a past run, we should fire after adding if (memory && !firing) { firingIndex = list.length - 1; queue.push(memory); } (function add(args) { jQuery.each(args, function (_, arg) { if (isFunction(arg)) { if (!options.unique || !self.has(arg)) { list.push(arg); } } else if (arg && arg.length && toType(arg) !== "string") { // Inspect recursively add(arg); } }); })(arguments); if (memory && !firing) { fire(); } } return this; }, // Remove a callback from the list remove: function remove() { jQuery.each(arguments, function (_, arg) { var index; while ((index = jQuery.inArray(arg, list, index)) > -1) { list.splice(index, 1); // Handle firing indexes if (index <= firingIndex) { firingIndex--; } } }); return this; }, // Check if a given callback is in the list. // If no argument is given, return whether or not list has callbacks attached. has: function has(fn) { return fn ? jQuery.inArray(fn, list) > -1 : list.length > 0; }, // Remove all callbacks from the list empty: function empty() { if (list) { list = []; } return this; }, // Disable .fire and .add // Abort any current/pending executions // Clear all callbacks and values disable: function disable() { _locked = queue = []; list = memory = ""; return this; }, disabled: function disabled() { return !list; }, // Disable .fire // Also disable .add unless we have memory (since it would have no effect) // Abort any pending executions lock: function lock() { _locked = queue = []; if (!memory && !firing) { list = memory = ""; } return this; }, locked: function locked() { return !!_locked; }, // Call all callbacks with the given context and arguments fireWith: function fireWith(context, args) { if (!_locked) { args = args || []; args = [context, args.slice ? args.slice() : args]; queue.push(args); if (!firing) { fire(); } } return this; }, // Call all the callbacks with the given arguments fire: function fire() { self.fireWith(this, arguments); return this; }, // To know if the callbacks have already been called at least once fired: function fired() { return !!_fired; } }; return self; }; function Identity(v) { return v; } function Thrower(ex) { throw ex; } function adoptValue(value, resolve, reject, noValue) { var method; try { // Check for promise aspect first to privilege synchronous behavior if (value && isFunction(method = value.promise)) { method.call(value).done(resolve).fail(reject); // Other thenables } else if (value && isFunction(method = value.then)) { method.call(value, resolve, reject); // Other non-thenables } else { // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: // * false: [ value ].slice( 0 ) => resolve( value ) // * true: [ value ].slice( 1 ) => resolve() resolve.apply(undefined, [value].slice(noValue)); } // For Promises/A+, convert exceptions into rejections // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in // Deferred#then to conditionally suppress rejection. } catch (value) { // Support: Android 4.0 only // Strict mode functions invoked without .call/.apply get global-object context reject.apply(undefined, [value]); } } jQuery.extend({ Deferred: function Deferred(func) { var tuples = [ // action, add listener, callbacks, // ... .then handlers, argument index, [final state] ["notify", "progress", jQuery.Callbacks("memory"), jQuery.Callbacks("memory"), 2], ["resolve", "done", jQuery.Callbacks("once memory"), jQuery.Callbacks("once memory"), 0, "resolved"], ["reject", "fail", jQuery.Callbacks("once memory"), jQuery.Callbacks("once memory"), 1, "rejected"]], _state = "pending", _promise = { state: function state() { return _state; }, always: function always() { deferred.done(arguments).fail(arguments); return this; }, "catch": function _catch(fn) { return _promise.then(null, fn); }, // Keep pipe for back-compat pipe: function pipe() /* fnDone, fnFail, fnProgress */{ var fns = arguments; return jQuery.Deferred(function (newDefer) { jQuery.each(tuples, function (i, tuple) { // Map tuples (progress, done, fail) to arguments (done, fail, progress) var fn = isFunction(fns[tuple[4]]) && fns[tuple[4]]; // deferred.progress(function() { bind to newDefer or newDefer.notify }) // deferred.done(function() { bind to newDefer or newDefer.resolve }) // deferred.fail(function() { bind to newDefer or newDefer.reject }) deferred[tuple[1]](function () { var returned = fn && fn.apply(this, arguments); if (returned && isFunction(returned.promise)) { returned.promise().progress(newDefer.notify).done(newDefer.resolve).fail(newDefer.reject); } else { newDefer[tuple[0] + "With"](this, fn ? [returned] : arguments); } }); }); fns = null; }).promise(); }, then: function then(onFulfilled, onRejected, onProgress) { var maxDepth = 0; function resolve(depth, deferred, handler, special) { return function () { var that = this, args = arguments, mightThrow = function mightThrow() { var returned, then; // Support: Promises/A+ section 2.3.3.3.3 // https://promisesaplus.com/#point-59 // Ignore double-resolution attempts if (depth < maxDepth) { return; } returned = handler.apply(that, args); // Support: Promises/A+ section 2.3.1 // https://promisesaplus.com/#point-48 if (returned === deferred.promise()) { throw new TypeError("Thenable self-resolution"); } // Support: Promises/A+ sections 2.3.3.1, 3.5 // https://promisesaplus.com/#point-54 // https://promisesaplus.com/#point-75 // Retrieve `then` only once then = returned && ( // Support: Promises/A+ section 2.3.4 // https://promisesaplus.com/#point-64 // Only check objects and functions for thenability (typeof returned === "undefined" ? "undefined" : _typeof(returned)) === "object" || typeof returned === "function") && returned.then; // Handle a returned thenable if (isFunction(then)) { // Special processors (notify) just wait for resolution if (special) { then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special)); // Normal processors (resolve) also hook into progress } else { // ...and disregard older resolution values maxDepth++; then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special), resolve(maxDepth, deferred, Identity, deferred.notifyWith)); } // Handle all other returned values } else { // Only substitute handlers pass on context // and multiple values (non-spec behavior) if (handler !== Identity) { that = undefined; args = [returned]; } // Process the value(s) // Default process is resolve (special || deferred.resolveWith)(that, args); } }, // Only normal processors (resolve) catch and reject exceptions process = special ? mightThrow : function () { try { mightThrow(); } catch (e) { if (jQuery.Deferred.exceptionHook) { jQuery.Deferred.exceptionHook(e, process.stackTrace); } // Support: Promises/A+ section 2.3.3.3.4.1 // https://promisesaplus.com/#point-61 // Ignore post-resolution exceptions if (depth + 1 >= maxDepth) { // Only substitute handlers pass on context // and multiple values (non-spec behavior) if (handler !== Thrower) { that = undefined; args = [e]; } deferred.rejectWith(that, args); } } }; // Support: Promises/A+ section 2.3.3.3.1 // https://promisesaplus.com/#point-57 // Re-resolve promises immediately to dodge false rejection from // subsequent errors if (depth) { process(); } else { // Call an optional hook to record the stack, in case of exception // since it's otherwise lost when execution goes async if (jQuery.Deferred.getStackHook) { process.stackTrace = jQuery.Deferred.getStackHook(); } window.setTimeout(process); } }; } return jQuery.Deferred(function (newDefer) { // progress_handlers.add( ... ) tuples[0][3].add(resolve(0, newDefer, isFunction(onProgress) ? onProgress : Identity, newDefer.notifyWith)); // fulfilled_handlers.add( ... ) tuples[1][3].add(resolve(0, newDefer, isFunction(onFulfilled) ? onFulfilled : Identity)); // rejected_handlers.add( ... ) tuples[2][3].add(resolve(0, newDefer, isFunction(onRejected) ? onRejected : Thrower)); }).promise(); }, // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function promise(obj) { return obj != null ? jQuery.extend(obj, _promise) : _promise; } }, deferred = {}; // Add list-specific methods jQuery.each(tuples, function (i, tuple) { var list = tuple[2], stateString = tuple[5]; // promise.progress = list.add // promise.done = list.add // promise.fail = list.add _promise[tuple[1]] = list.add; // Handle state if (stateString) { list.add(function () { // state = "resolved" (i.e., fulfilled) // state = "rejected" _state = stateString; }, // rejected_callbacks.disable // fulfilled_callbacks.disable tuples[3 - i][2].disable, // rejected_handlers.disable // fulfilled_handlers.disable tuples[3 - i][3].disable, // progress_callbacks.lock tuples[0][2].lock, // progress_handlers.lock tuples[0][3].lock); } // progress_handlers.fire // fulfilled_handlers.fire // rejected_handlers.fire list.add(tuple[3].fire); // deferred.notify = function() { deferred.notifyWith(...) } // deferred.resolve = function() { deferred.resolveWith(...) } // deferred.reject = function() { deferred.rejectWith(...) } deferred[tuple[0]] = function () { deferred[tuple[0] + "With"](this === deferred ? undefined : this, arguments); return this; }; // deferred.notifyWith = list.fireWith // deferred.resolveWith = list.fireWith // deferred.rejectWith = list.fireWith deferred[tuple[0] + "With"] = list.fireWith; }); // Make the deferred a promise _promise.promise(deferred); // Call given func if any if (func) { func.call(deferred, deferred); } // All done! return deferred; }, // Deferred helper when: function when(singleValue) { var // count of uncompleted subordinates remaining = arguments.length, // count of unprocessed arguments i = remaining, // subordinate fulfillment data resolveContexts = Array(i), resolveValues = _slice.call(arguments), // the master Deferred master = jQuery.Deferred(), // subordinate callback factory updateFunc = function updateFunc(i) { return function (value) { resolveContexts[i] = this; resolveValues[i] = arguments.length > 1 ? _slice.call(arguments) : value; if (! --remaining) { master.resolveWith(resolveContexts, resolveValues); } }; }; // Single- and empty arguments are adopted like Promise.resolve if (remaining <= 1) { adoptValue(singleValue, master.done(updateFunc(i)).resolve, master.reject, !remaining); // Use .then() to unwrap secondary thenables (cf. gh-3000) if (master.state() === "pending" || isFunction(resolveValues[i] && resolveValues[i].then)) { return master.then(); } } // Multiple arguments are aggregated like Promise.all array elements while (i--) { adoptValue(resolveValues[i], updateFunc(i), master.reject); } return master.promise(); } }); // These usually indicate a programmer mistake during development, // warn about them ASAP rather than swallowing them by default. var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; jQuery.Deferred.exceptionHook = function (error, stack) { // Support: IE 8 - 9 only // Console exists when dev tools are open, which can happen at any time if (window.console && window.console.warn && error && rerrorNames.test(error.name)) { window.console.warn("jQuery.Deferred exception: " + error.message, error.stack, stack); } }; jQuery.readyException = function (error) { window.setTimeout(function () { throw error; }); }; // The deferred used on DOM ready var readyList = jQuery.Deferred(); jQuery.fn.ready = function (fn) { readyList.then(fn) // Wrap jQuery.readyException in a function so that the lookup // happens at the time of error handling instead of callback // registration. .catch(function (error) { jQuery.readyException(error); }); return this; }; jQuery.extend({ // Is the DOM ready to be used? Set to true once it occurs. isReady: false, // A counter to track how many items to wait for before // the ready event fires. See #6781 readyWait: 1, // Handle when the DOM is ready ready: function ready(wait) { // Abort if there are pending holds or we're already ready if (wait === true ? --jQuery.readyWait : jQuery.isReady) { return; } // Remember that the DOM is ready jQuery.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be if (wait !== true && --jQuery.readyWait > 0) { return; } // If there are functions bound, to execute readyList.resolveWith(document, [jQuery]); } }); jQuery.ready.then = readyList.then; // The ready event handler and self cleanup method function completed() { document.removeEventListener("DOMContentLoaded", completed); window.removeEventListener("load", completed); jQuery.ready(); } // Catch cases where $(document).ready() is called // after the browser event has already occurred. // Support: IE <=9 - 10 only // Older IE sometimes signals "interactive" too soon if (document.readyState === "complete" || document.readyState !== "loading" && !document.documentElement.doScroll) { // Handle it asynchronously to allow scripts the opportunity to delay ready window.setTimeout(jQuery.ready); } else { // Use the handy event callback document.addEventListener("DOMContentLoaded", completed); // A fallback to window.onload, that will always work window.addEventListener("load", completed); } // Multifunctional method to get and set values of a collection // The value/s can optionally be executed if it's a function var access = function access(elems, fn, key, value, chainable, emptyGet, raw) { var i = 0, len = elems.length, bulk = key == null; // Sets many values if (toType(key) === "object") { chainable = true; for (i in key) { access(elems, fn, i, key[i], true, emptyGet, raw); } // Sets one value } else if (value !== undefined) { chainable = true; if (!isFunction(value)) { raw = true; } if (bulk) { // Bulk operations run against the entire set if (raw) { fn.call(elems, value); fn = null; // ...except when executing function values } else { bulk = fn; fn = function fn(elem, key, value) { return bulk.call(jQuery(elem), value); }; } } if (fn) { for (; i < len; i++) { fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key))); } } } if (chainable) { return elems; } // Gets if (bulk) { return fn.call(elems); } return len ? fn(elems[0], key) : emptyGet; }; // Matches dashed string for camelizing var rmsPrefix = /^-ms-/, rdashAlpha = /-([a-z])/g; // Used by camelCase as callback to replace() function fcamelCase(all, letter) { return letter.toUpperCase(); } // Convert dashed to camelCase; used by the css and data modules // Support: IE <=9 - 11, Edge 12 - 15 // Microsoft forgot to hump their vendor prefix (#9572) function camelCase(string) { return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase); } var acceptData = function acceptData(owner) { // Accepts only: // - Node // - Node.ELEMENT_NODE // - Node.DOCUMENT_NODE // - Object // - Any return owner.nodeType === 1 || owner.nodeType === 9 || !+owner.nodeType; }; function Data() { this.expando = jQuery.expando + Data.uid++; } Data.uid = 1; Data.prototype = { cache: function cache(owner) { // Check if the owner object already has a cache var value = owner[this.expando]; // If not, create one if (!value) { value = {}; // We can accept data for non-element nodes in modern browsers, // but we should not, see #8335. // Always return an empty object. if (acceptData(owner)) { // If it is a node unlikely to be stringify-ed or looped over // use plain assignment if (owner.nodeType) { owner[this.expando] = value; // Otherwise secure it in a non-enumerable property // configurable must be true to allow the property to be // deleted when data is removed } else { Object.defineProperty(owner, this.expando, { value: value, configurable: true }); } } } return value; }, set: function set(owner, data, value) { var prop, cache = this.cache(owner); // Handle: [ owner, key, value ] args // Always use camelCase key (gh-2257) if (typeof data === "string") { cache[camelCase(data)] = value; // Handle: [ owner, { properties } ] args } else { // Copy the properties one-by-one to the cache object for (prop in data) { cache[camelCase(prop)] = data[prop]; } } return cache; }, get: function get(owner, key) { return key === undefined ? this.cache(owner) : // Always use camelCase key (gh-2257) owner[this.expando] && owner[this.expando][camelCase(key)]; }, access: function access(owner, key, value) { // In cases where either: // // 1. No key was specified // 2. A string key was specified, but no value provided // // Take the "read" path and allow the get method to determine // which value to return, respectively either: // // 1. The entire cache object // 2. The data stored at the key // if (key === undefined || key && typeof key === "string" && value === undefined) { return this.get(owner, key); } // When the key is not a string, or both a key and value // are specified, set or extend (existing objects) with either: // // 1. An object of properties // 2. A key and value // this.set(owner, key, value); // Since the "set" path can have two possible entry points // return the expected data based on which path was taken[*] return value !== undefined ? value : key; }, remove: function remove(owner, key) { var i, cache = owner[this.expando]; if (cache === undefined) { return; } if (key !== undefined) { // Support array or space separated string of keys if (Array.isArray(key)) { // If key is an array of keys... // We always set camelCase keys, so remove that. key = key.map(camelCase); } else { key = camelCase(key); // If a key with the spaces exists, use it. // Otherwise, create an array by matching non-whitespace key = key in cache ? [key] : key.match(rnothtmlwhite) || []; } i = key.length; while (i--) { delete cache[key[i]]; } } // Remove the expando if there's no more data if (key === undefined || jQuery.isEmptyObject(cache)) { // Support: Chrome <=35 - 45 // Webkit & Blink performance suffers when deleting properties // from DOM nodes, so set to undefined instead // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) if (owner.nodeType) { owner[this.expando] = undefined; } else { delete owner[this.expando]; } } }, hasData: function hasData(owner) { var cache = owner[this.expando]; return cache !== undefined && !jQuery.isEmptyObject(cache); } }; var dataPriv = new Data(); var dataUser = new Data(); // Implementation Summary // // 1. Enforce API surface and semantic compatibility with 1.9.x branch // 2. Improve the module's maintainability by reducing the storage // paths to a single mechanism. // 3. Use the same single mechanism to support "private" and "user" data. // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) // 5. Avoid exposing implementation details on user objects (eg. expando properties) // 6. Provide a clear path for implementation upgrade to WeakMap in 2014 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, rmultiDash = /[A-Z]/g; function getData(data) { if (data === "true") { return true; } if (data === "false") { return false; } if (data === "null") { return null; } // Only convert to a number if it doesn't change the string if (data === +data + "") { return +data; } if (rbrace.test(data)) { return JSON.parse(data); } return data; } function dataAttr(elem, key, data) { var name; // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if (data === undefined && elem.nodeType === 1) { name = "data-" + key.replace(rmultiDash, "-$&").toLowerCase(); data = elem.getAttribute(name); if (typeof data === "string") { try { data = getData(data); } catch (e) {} // Make sure we set the data so it isn't changed later dataUser.set(elem, key, data); } else { data = undefined; } } return data; } jQuery.extend({ hasData: function hasData(elem) { return dataUser.hasData(elem) || dataPriv.hasData(elem); }, data: function data(elem, name, _data) { return dataUser.access(elem, name, _data); }, removeData: function removeData(elem, name) { dataUser.remove(elem, name); }, // TODO: Now that all calls to _data and _removeData have been replaced // with direct calls to dataPriv methods, these can be deprecated. _data: function _data(elem, name, data) { return dataPriv.access(elem, name, data); }, _removeData: function _removeData(elem, name) { dataPriv.remove(elem, name); } }); jQuery.fn.extend({ data: function data(key, value) { var i, name, data, elem = this[0], attrs = elem && elem.attributes; // Gets all values if (key === undefined) { if (this.length) { data = dataUser.get(elem); if (elem.nodeType === 1 && !dataPriv.get(elem, "hasDataAttrs")) { i = attrs.length; while (i--) { // Support: IE 11 only // The attrs elements can be null (#14894) if (attrs[i]) { name = attrs[i].name; if (name.indexOf("data-") === 0) { name = camelCase(name.slice(5)); dataAttr(elem, name, data[name]); } } } dataPriv.set(elem, "hasDataAttrs", true); } } return data; } // Sets multiple values if ((typeof key === "undefined" ? "undefined" : _typeof(key)) === "object") { return this.each(function () { dataUser.set(this, key); }); } return access(this, function (value) { var data; // The calling jQuery object (element matches) is not empty // (and therefore has an element appears at this[ 0 ]) and the // `value` parameter was not undefined. An empty jQuery object // will result in `undefined` for elem = this[ 0 ] which will // throw an exception if an attempt to read a data cache is made. if (elem && value === undefined) { // Attempt to get data from the cache // The key will always be camelCased in Data data = dataUser.get(elem, key); if (data !== undefined) { return data; } // Attempt to "discover" the data in // HTML5 custom data-* attrs data = dataAttr(elem, key); if (data !== undefined) { return data; } // We tried really hard, but the data doesn't exist. return; } // Set the data... this.each(function () { // We always store the camelCased key dataUser.set(this, key, value); }); }, null, value, arguments.length > 1, null, true); }, removeData: function removeData(key) { return this.each(function () { dataUser.remove(this, key); }); } }); jQuery.extend({ queue: function queue(elem, type, data) { var queue; if (elem) { type = (type || "fx") + "queue"; queue = dataPriv.get(elem, type); // Speed up dequeue by getting out quickly if this is just a lookup if (data) { if (!queue || Array.isArray(data)) { queue = dataPriv.access(elem, type, jQuery.makeArray(data)); } else { queue.push(data); } } return queue || []; } }, dequeue: function dequeue(elem, type) { type = type || "fx"; var queue = jQuery.queue(elem, type), startLength = queue.length, fn = queue.shift(), hooks = jQuery._queueHooks(elem, type), next = function next() { jQuery.dequeue(elem, type); }; // If the fx queue is dequeued, always remove the progress sentinel if (fn === "inprogress") { fn = queue.shift(); startLength--; } if (fn) { // Add a progress sentinel to prevent the fx queue from being // automatically dequeued if (type === "fx") { queue.unshift("inprogress"); } // Clear up the last queue stop function delete hooks.stop; fn.call(elem, next, hooks); } if (!startLength && hooks) { hooks.empty.fire(); } }, // Not public - generate a queueHooks object, or return the current one _queueHooks: function _queueHooks(elem, type) { var key = type + "queueHooks"; return dataPriv.get(elem, key) || dataPriv.access(elem, key, { empty: jQuery.Callbacks("once memory").add(function () { dataPriv.remove(elem, [type + "queue", key]); }) }); } }); jQuery.fn.extend({ queue: function queue(type, data) { var setter = 2; if (typeof type !== "string") { data = type; type = "fx"; setter--; } if (arguments.length < setter) { return jQuery.queue(this[0], type); } return data === undefined ? this : this.each(function () { var queue = jQuery.queue(this, type, data); // Ensure a hooks for this queue jQuery._queueHooks(this, type); if (type === "fx" && queue[0] !== "inprogress") { jQuery.dequeue(this, type); } }); }, dequeue: function dequeue(type) { return this.each(function () { jQuery.dequeue(this, type); }); }, clearQueue: function clearQueue(type) { return this.queue(type || "fx", []); }, // Get a promise resolved when queues of a certain type // are emptied (fx is the type by default) promise: function promise(type, obj) { var tmp, count = 1, defer = jQuery.Deferred(), elements = this, i = this.length, resolve = function resolve() { if (! --count) { defer.resolveWith(elements, [elements]); } }; if (typeof type !== "string") { obj = type; type = undefined; } type = type || "fx"; while (i--) { tmp = dataPriv.get(elements[i], type + "queueHooks"); if (tmp && tmp.empty) { count++; tmp.empty.add(resolve); } } resolve(); return defer.promise(obj); } }); var pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source; var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i"); var cssExpand = ["Top", "Right", "Bottom", "Left"]; var isHiddenWithinTree = function isHiddenWithinTree(elem, el) { // isHiddenWithinTree might be called from jQuery#filter function; // in that case, element will be second argument elem = el || elem; // Inline style trumps all return elem.style.display === "none" || elem.style.display === "" && // Otherwise, check computed style // Support: Firefox <=43 - 45 // Disconnected elements can have computed display: none, so first confirm that elem is // in the document. jQuery.contains(elem.ownerDocument, elem) && jQuery.css(elem, "display") === "none"; }; var swap = function swap(elem, options, callback, args) { var ret, name, old = {}; // Remember the old values, and insert the new ones for (name in options) { old[name] = elem.style[name]; elem.style[name] = options[name]; } ret = callback.apply(elem, args || []); // Revert the old values for (name in options) { elem.style[name] = old[name]; } return ret; }; function adjustCSS(elem, prop, valueParts, tween) { var adjusted, scale, maxIterations = 20, currentValue = tween ? function () { return tween.cur(); } : function () { return jQuery.css(elem, prop, ""); }, initial = currentValue(), unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? "" : "px"), // Starting value computation is required for potential unit mismatches initialInUnit = (jQuery.cssNumber[prop] || unit !== "px" && +initial) && rcssNum.exec(jQuery.css(elem, prop)); if (initialInUnit && initialInUnit[3] !== unit) { // Support: Firefox <=54 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) initial = initial / 2; // Trust units reported by jQuery.css unit = unit || initialInUnit[3]; // Iteratively approximate from a nonzero starting point initialInUnit = +initial || 1; while (maxIterations--) { // Evaluate and update our best guess (doubling guesses that zero out). // Finish if the scale equals or crosses 1 (making the old*new product non-positive). jQuery.style(elem, prop, initialInUnit + unit); if ((1 - scale) * (1 - (scale = currentValue() / initial || 0.5)) <= 0) { maxIterations = 0; } initialInUnit = initialInUnit / scale; } initialInUnit = initialInUnit * 2; jQuery.style(elem, prop, initialInUnit + unit); // Make sure we update the tween properties later on valueParts = valueParts || []; } if (valueParts) { initialInUnit = +initialInUnit || +initial || 0; // Apply relative offset (+=/-=) if specified adjusted = valueParts[1] ? initialInUnit + (valueParts[1] + 1) * valueParts[2] : +valueParts[2]; if (tween) { tween.unit = unit; tween.start = initialInUnit; tween.end = adjusted; } } return adjusted; } var defaultDisplayMap = {}; function getDefaultDisplay(elem) { var temp, doc = elem.ownerDocument, nodeName = elem.nodeName, display = defaultDisplayMap[nodeName]; if (display) { return display; } temp = doc.body.appendChild(doc.createElement(nodeName)); display = jQuery.css(temp, "display"); temp.parentNode.removeChild(temp); if (display === "none") { display = "block"; } defaultDisplayMap[nodeName] = display; return display; } function showHide(elements, show) { var display, elem, values = [], index = 0, length = elements.length; // Determine new display value for elements that need to change for (; index < length; index++) { elem = elements[index]; if (!elem.style) { continue; } display = elem.style.display; if (show) { // Since we force visibility upon cascade-hidden elements, an immediate (and slow) // check is required in this first loop unless we have a nonempty display value (either // inline or about-to-be-restored) if (display === "none") { values[index] = dataPriv.get(elem, "display") || null; if (!values[index]) { elem.style.display = ""; } } if (elem.style.display === "" && isHiddenWithinTree(elem)) { values[index] = getDefaultDisplay(elem); } } else { if (display !== "none") { values[index] = "none"; // Remember what we're overwriting dataPriv.set(elem, "display", display); } } } // Set the display of the elements in a second loop to avoid constant reflow for (index = 0; index < length; index++) { if (values[index] != null) { elements[index].style.display = values[index]; } } return elements; } jQuery.fn.extend({ show: function show() { return showHide(this, true); }, hide: function hide() { return showHide(this); }, toggle: function toggle(state) { if (typeof state === "boolean") { return state ? this.show() : this.hide(); } return this.each(function () { if (isHiddenWithinTree(this)) { jQuery(this).show(); } else { jQuery(this).hide(); } }); } }); var rcheckableType = /^(?:checkbox|radio)$/i; var rtagName = /<([a-z][^\/\0>\x20\t\r\n\f]+)/i; var rscriptType = /^$|^module$|\/(?:java|ecma)script/i; // We have to close these tags to support XHTML (#13200) var wrapMap = { // Support: IE <=9 only option: [1, ""], // XHTML parsers do not magically insert elements in the // same way that tag soup parsers do. So we cannot shorten // this by omitting or other required elements. thead: [1, "", "
"], col: [2, "", "
"], tr: [2, "", "
"], td: [3, "", "
"], _default: [0, "", ""] }; // Support: IE <=9 only wrapMap.optgroup = wrapMap.option; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; function getAll(context, tag) { // Support: IE <=9 - 11 only // Use typeof to avoid zero-argument method invocation on host objects (#15151) var ret; if (typeof context.getElementsByTagName !== "undefined") { ret = context.getElementsByTagName(tag || "*"); } else if (typeof context.querySelectorAll !== "undefined") { ret = context.querySelectorAll(tag || "*"); } else { ret = []; } if (tag === undefined || tag && nodeName(context, tag)) { return jQuery.merge([context], ret); } return ret; } // Mark scripts as having already been evaluated function setGlobalEval(elems, refElements) { var i = 0, l = elems.length; for (; i < l; i++) { dataPriv.set(elems[i], "globalEval", !refElements || dataPriv.get(refElements[i], "globalEval")); } } var rhtml = /<|&#?\w+;/; function buildFragment(elems, context, scripts, selection, ignored) { var elem, tmp, tag, wrap, contains, j, fragment = context.createDocumentFragment(), nodes = [], i = 0, l = elems.length; for (; i < l; i++) { elem = elems[i]; if (elem || elem === 0) { // Add nodes directly if (toType(elem) === "object") { // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge(nodes, elem.nodeType ? [elem] : elem); // Convert non-html into a text node } else if (!rhtml.test(elem)) { nodes.push(context.createTextNode(elem)); // Convert html into DOM nodes } else { tmp = tmp || fragment.appendChild(context.createElement("div")); // Deserialize a standard representation tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase(); wrap = wrapMap[tag] || wrapMap._default; tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2]; // Descend through wrappers to the right content j = wrap[0]; while (j--) { tmp = tmp.lastChild; } // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge(nodes, tmp.childNodes); // Remember the top-level container tmp = fragment.firstChild; // Ensure the created nodes are orphaned (#12392) tmp.textContent = ""; } } } // Remove wrapper from fragment fragment.textContent = ""; i = 0; while (elem = nodes[i++]) { // Skip elements already in the context collection (trac-4087) if (selection && jQuery.inArray(elem, selection) > -1) { if (ignored) { ignored.push(elem); } continue; } contains = jQuery.contains(elem.ownerDocument, elem); // Append to fragment tmp = getAll(fragment.appendChild(elem), "script"); // Preserve script evaluation history if (contains) { setGlobalEval(tmp); } // Capture executables if (scripts) { j = 0; while (elem = tmp[j++]) { if (rscriptType.test(elem.type || "")) { scripts.push(elem); } } } } return fragment; } (function () { var fragment = document.createDocumentFragment(), div = fragment.appendChild(document.createElement("div")), input = document.createElement("input"); // Support: Android 4.0 - 4.3 only // Check state lost if the name is set (#11217) // Support: Windows Web Apps (WWA) // `name` and `type` must use .setAttribute for WWA (#14901) input.setAttribute("type", "radio"); input.setAttribute("checked", "checked"); input.setAttribute("name", "t"); div.appendChild(input); // Support: Android <=4.1 only // Older WebKit doesn't clone checked state correctly in fragments support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked; // Support: IE <=11 only // Make sure textarea (and checkbox) defaultValue is properly cloned div.innerHTML = ""; support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue; })(); var documentElement = document.documentElement; var rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, rtypenamespace = /^([^.]*)(?:\.(.+)|)/; function returnTrue() { return true; } function returnFalse() { return false; } // Support: IE <=9 only // See #13393 for more info function safeActiveElement() { try { return document.activeElement; } catch (err) {} } function _on(elem, types, selector, data, fn, one) { var origFn, type; // Types can be a map of types/handlers if ((typeof types === "undefined" ? "undefined" : _typeof(types)) === "object") { // ( types-Object, selector, data ) if (typeof selector !== "string") { // ( types-Object, data ) data = data || selector; selector = undefined; } for (type in types) { _on(elem, type, selector, data, types[type], one); } return elem; } if (data == null && fn == null) { // ( types, fn ) fn = selector; data = selector = undefined; } else if (fn == null) { if (typeof selector === "string") { // ( types, selector, fn ) fn = data; data = undefined; } else { // ( types, data, fn ) fn = data; data = selector; selector = undefined; } } if (fn === false) { fn = returnFalse; } else if (!fn) { return elem; } if (one === 1) { origFn = fn; fn = function fn(event) { // Can use an empty set, since event contains the info jQuery().off(event); return origFn.apply(this, arguments); }; // Use same guid so caller can remove using origFn fn.guid = origFn.guid || (origFn.guid = jQuery.guid++); } return elem.each(function () { jQuery.event.add(this, types, fn, data, selector); }); } /* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. */ jQuery.event = { global: {}, add: function add(elem, types, handler, data, selector) { var handleObjIn, eventHandle, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.get(elem); // Don't attach events to noData or text/comment nodes (but allow plain objects) if (!elemData) { return; } // Caller can pass in an object of custom data in lieu of the handler if (handler.handler) { handleObjIn = handler; handler = handleObjIn.handler; selector = handleObjIn.selector; } // Ensure that invalid selectors throw exceptions at attach time // Evaluate against documentElement in case elem is a non-element node (e.g., document) if (selector) { jQuery.find.matchesSelector(documentElement, selector); } // Make sure that the handler has a unique ID, used to find/remove it later if (!handler.guid) { handler.guid = jQuery.guid++; } // Init the element's event structure and main handler, if this is the first if (!(events = elemData.events)) { events = elemData.events = {}; } if (!(eventHandle = elemData.handle)) { eventHandle = elemData.handle = function (e) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply(elem, arguments) : undefined; }; } // Handle multiple events separated by a space types = (types || "").match(rnothtmlwhite) || [""]; t = types.length; while (t--) { tmp = rtypenamespace.exec(types[t]) || []; type = origType = tmp[1]; namespaces = (tmp[2] || "").split(".").sort(); // There *must* be a type, no attaching namespace-only handlers if (!type) { continue; } // If event changes its type, use the special event handlers for the changed type special = jQuery.event.special[type] || {}; // If selector defined, determine special event api type, otherwise given type type = (selector ? special.delegateType : special.bindType) || type; // Update special based on newly reset type special = jQuery.event.special[type] || {}; // handleObj is passed to all event handlers handleObj = jQuery.extend({ type: type, origType: origType, data: data, handler: handler, guid: handler.guid, selector: selector, needsContext: selector && jQuery.expr.match.needsContext.test(selector), namespace: namespaces.join(".") }, handleObjIn); // Init the event handler queue if we're the first if (!(handlers = events[type])) { handlers = events[type] = []; handlers.delegateCount = 0; // Only use addEventListener if the special events handler returns false if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) { if (elem.addEventListener) { elem.addEventListener(type, eventHandle); } } } if (special.add) { special.add.call(elem, handleObj); if (!handleObj.handler.guid) { handleObj.handler.guid = handler.guid; } } // Add to the element's handler list, delegates in front if (selector) { handlers.splice(handlers.delegateCount++, 0, handleObj); } else { handlers.push(handleObj); } // Keep track of which events have ever been used, for event optimization jQuery.event.global[type] = true; } }, // Detach an event or set of events from an element remove: function remove(elem, types, handler, selector, mappedTypes) { var j, origCount, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.hasData(elem) && dataPriv.get(elem); if (!elemData || !(events = elemData.events)) { return; } // Once for each type.namespace in types; type may be omitted types = (types || "").match(rnothtmlwhite) || [""]; t = types.length; while (t--) { tmp = rtypenamespace.exec(types[t]) || []; type = origType = tmp[1]; namespaces = (tmp[2] || "").split(".").sort(); // Unbind all events (on this namespace, if provided) for the element if (!type) { for (type in events) { jQuery.event.remove(elem, type + types[t], handler, selector, true); } continue; } special = jQuery.event.special[type] || {}; type = (selector ? special.delegateType : special.bindType) || type; handlers = events[type] || []; tmp = tmp[2] && new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)"); // Remove matching events origCount = j = handlers.length; while (j--) { handleObj = handlers[j]; if ((mappedTypes || origType === handleObj.origType) && (!handler || handler.guid === handleObj.guid) && (!tmp || tmp.test(handleObj.namespace)) && (!selector || selector === handleObj.selector || selector === "**" && handleObj.selector)) { handlers.splice(j, 1); if (handleObj.selector) { handlers.delegateCount--; } if (special.remove) { special.remove.call(elem, handleObj); } } } // Remove generic event handler if we removed something and no more handlers exist // (avoids potential for endless recursion during removal of special event handlers) if (origCount && !handlers.length) { if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) { jQuery.removeEvent(elem, type, elemData.handle); } delete events[type]; } } // Remove data and the expando if it's no longer used if (jQuery.isEmptyObject(events)) { dataPriv.remove(elem, "handle events"); } }, dispatch: function dispatch(nativeEvent) { // Make a writable jQuery.Event from the native event object var event = jQuery.event.fix(nativeEvent); var i, j, ret, matched, handleObj, handlerQueue, args = new Array(arguments.length), handlers = (dataPriv.get(this, "events") || {})[event.type] || [], special = jQuery.event.special[event.type] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event args[0] = event; for (i = 1; i < arguments.length; i++) { args[i] = arguments[i]; } event.delegateTarget = this; // Call the preDispatch hook for the mapped type, and let it bail if desired if (special.preDispatch && special.preDispatch.call(this, event) === false) { return; } // Determine handlers handlerQueue = jQuery.event.handlers.call(this, event, handlers); // Run delegates first; they may want to stop propagation beneath us i = 0; while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) { event.currentTarget = matched.elem; j = 0; while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) { // Triggered event must either 1) have no namespace, or 2) have namespace(s) // a subset or equal to those in the bound event (both can have no namespace). if (!event.rnamespace || event.rnamespace.test(handleObj.namespace)) { event.handleObj = handleObj; event.data = handleObj.data; ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply(matched.elem, args); if (ret !== undefined) { if ((event.result = ret) === false) { event.preventDefault(); event.stopPropagation(); } } } } } // Call the postDispatch hook for the mapped type if (special.postDispatch) { special.postDispatch.call(this, event); } return event.result; }, handlers: function handlers(event, _handlers) { var i, handleObj, sel, matchedHandlers, matchedSelectors, handlerQueue = [], delegateCount = _handlers.delegateCount, cur = event.target; // Find delegate handlers if (delegateCount && // Support: IE <=9 // Black-hole SVG instance trees (trac-13180) cur.nodeType && // Support: Firefox <=42 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click // Support: IE 11 only // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) !(event.type === "click" && event.button >= 1)) { for (; cur !== this; cur = cur.parentNode || this) { // Don't check non-elements (#13208) // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) if (cur.nodeType === 1 && !(event.type === "click" && cur.disabled === true)) { matchedHandlers = []; matchedSelectors = {}; for (i = 0; i < delegateCount; i++) { handleObj = _handlers[i]; // Don't conflict with Object.prototype properties (#13203) sel = handleObj.selector + " "; if (matchedSelectors[sel] === undefined) { matchedSelectors[sel] = handleObj.needsContext ? jQuery(sel, this).index(cur) > -1 : jQuery.find(sel, this, null, [cur]).length; } if (matchedSelectors[sel]) { matchedHandlers.push(handleObj); } } if (matchedHandlers.length) { handlerQueue.push({ elem: cur, handlers: matchedHandlers }); } } } } // Add the remaining (directly-bound) handlers cur = this; if (delegateCount < _handlers.length) { handlerQueue.push({ elem: cur, handlers: _handlers.slice(delegateCount) }); } return handlerQueue; }, addProp: function addProp(name, hook) { Object.defineProperty(jQuery.Event.prototype, name, { enumerable: true, configurable: true, get: isFunction(hook) ? function () { if (this.originalEvent) { return hook(this.originalEvent); } } : function () { if (this.originalEvent) { return this.originalEvent[name]; } }, set: function set(value) { Object.defineProperty(this, name, { enumerable: true, configurable: true, writable: true, value: value }); } }); }, fix: function fix(originalEvent) { return originalEvent[jQuery.expando] ? originalEvent : new jQuery.Event(originalEvent); }, special: { load: { // Prevent triggered image.load events from bubbling to window.load noBubble: true }, focus: { // Fire native event if possible so blur/focus sequence is correct trigger: function trigger() { if (this !== safeActiveElement() && this.focus) { this.focus(); return false; } }, delegateType: "focusin" }, blur: { trigger: function trigger() { if (this === safeActiveElement() && this.blur) { this.blur(); return false; } }, delegateType: "focusout" }, click: { // For checkbox, fire native event so checked state will be right trigger: function trigger() { if (this.type === "checkbox" && this.click && nodeName(this, "input")) { this.click(); return false; } }, // For cross-browser consistency, don't fire native .click() on links _default: function _default(event) { return nodeName(event.target, "a"); } }, beforeunload: { postDispatch: function postDispatch(event) { // Support: Firefox 20+ // Firefox doesn't alert if the returnValue field is not set. if (event.result !== undefined && event.originalEvent) { event.originalEvent.returnValue = event.result; } } } } }; jQuery.removeEvent = function (elem, type, handle) { // This "if" is needed for plain objects if (elem.removeEventListener) { elem.removeEventListener(type, handle); } }; jQuery.Event = function (src, props) { // Allow instantiation without the 'new' keyword if (!(this instanceof jQuery.Event)) { return new jQuery.Event(src, props); } // Event object if (src && src.type) { this.originalEvent = src; this.type = src.type; // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined && // Support: Android <=2.3 only src.returnValue === false ? returnTrue : returnFalse; // Create target properties // Support: Safari <=6 - 7 only // Target should not be a text node (#504, #13143) this.target = src.target && src.target.nodeType === 3 ? src.target.parentNode : src.target; this.currentTarget = src.currentTarget; this.relatedTarget = src.relatedTarget; // Event type } else { this.type = src; } // Put explicitly provided properties onto the event object if (props) { jQuery.extend(this, props); } // Create a timestamp if incoming event doesn't have one this.timeStamp = src && src.timeStamp || Date.now(); // Mark it as fixed this[jQuery.expando] = true; }; // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { constructor: jQuery.Event, isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse, isSimulated: false, preventDefault: function preventDefault() { var e = this.originalEvent; this.isDefaultPrevented = returnTrue; if (e && !this.isSimulated) { e.preventDefault(); } }, stopPropagation: function stopPropagation() { var e = this.originalEvent; this.isPropagationStopped = returnTrue; if (e && !this.isSimulated) { e.stopPropagation(); } }, stopImmediatePropagation: function stopImmediatePropagation() { var e = this.originalEvent; this.isImmediatePropagationStopped = returnTrue; if (e && !this.isSimulated) { e.stopImmediatePropagation(); } this.stopPropagation(); } }; // Includes all common event props including KeyEvent and MouseEvent specific props jQuery.each({ altKey: true, bubbles: true, cancelable: true, changedTouches: true, ctrlKey: true, detail: true, eventPhase: true, metaKey: true, pageX: true, pageY: true, shiftKey: true, view: true, "char": true, charCode: true, key: true, keyCode: true, button: true, buttons: true, clientX: true, clientY: true, offsetX: true, offsetY: true, pointerId: true, pointerType: true, screenX: true, screenY: true, targetTouches: true, toElement: true, touches: true, which: function which(event) { var button = event.button; // Add which for key events if (event.which == null && rkeyEvent.test(event.type)) { return event.charCode != null ? event.charCode : event.keyCode; } // Add which for click: 1 === left; 2 === middle; 3 === right if (!event.which && button !== undefined && rmouseEvent.test(event.type)) { if (button & 1) { return 1; } if (button & 2) { return 3; } if (button & 4) { return 2; } return 0; } return event.which; } }, jQuery.event.addProp); // Create mouseenter/leave events using mouseover/out and event-time checks // so that event delegation works in jQuery. // Do the same for pointerenter/pointerleave and pointerover/pointerout // // Support: Safari 7 only // Safari sends mouseenter too often; see: // https://bugs.chromium.org/p/chromium/issues/detail?id=470258 // for the description of the bug (it existed in older Chrome versions as well). jQuery.each({ mouseenter: "mouseover", mouseleave: "mouseout", pointerenter: "pointerover", pointerleave: "pointerout" }, function (orig, fix) { jQuery.event.special[orig] = { delegateType: fix, bindType: fix, handle: function handle(event) { var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj; // For mouseenter/leave call the handler if related is outside the target. // NB: No relatedTarget if the mouse left/entered the browser window if (!related || related !== target && !jQuery.contains(target, related)) { event.type = handleObj.origType; ret = handleObj.handler.apply(this, arguments); event.type = fix; } return ret; } }; }); jQuery.fn.extend({ on: function on(types, selector, data, fn) { return _on(this, types, selector, data, fn); }, one: function one(types, selector, data, fn) { return _on(this, types, selector, data, fn, 1); }, off: function off(types, selector, fn) { var handleObj, type; if (types && types.preventDefault && types.handleObj) { // ( event ) dispatched jQuery.Event handleObj = types.handleObj; jQuery(types.delegateTarget).off(handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler); return this; } if ((typeof types === "undefined" ? "undefined" : _typeof(types)) === "object") { // ( types-object [, selector] ) for (type in types) { this.off(type, selector, types[type]); } return this; } if (selector === false || typeof selector === "function") { // ( types [, fn] ) fn = selector; selector = undefined; } if (fn === false) { fn = returnFalse; } return this.each(function () { jQuery.event.remove(this, types, fn, selector); }); } }); var /* eslint-disable max-len */ // See https://github.com/eslint/eslint/issues/3229 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, /* eslint-enable */ // Support: IE <=10 - 11, Edge 12 - 13 only // In IE/Edge using regex groups here causes severe slowdowns. // See https://connect.microsoft.com/IE/feedback/details/1736512/ rnoInnerhtml = /\s*$/g; // Prefer a tbody over its parent table for containing new rows function manipulationTarget(elem, content) { if (nodeName(elem, "table") && nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr")) { return jQuery(elem).children("tbody")[0] || elem; } return elem; } // Replace/restore the type attribute of script elements for safe DOM manipulation function disableScript(elem) { elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; return elem; } function restoreScript(elem) { if ((elem.type || "").slice(0, 5) === "true/") { elem.type = elem.type.slice(5); } else { elem.removeAttribute("type"); } return elem; } function cloneCopyEvent(src, dest) { var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; if (dest.nodeType !== 1) { return; } // 1. Copy private data: events, handlers, etc. if (dataPriv.hasData(src)) { pdataOld = dataPriv.access(src); pdataCur = dataPriv.set(dest, pdataOld); events = pdataOld.events; if (events) { delete pdataCur.handle; pdataCur.events = {}; for (type in events) { for (i = 0, l = events[type].length; i < l; i++) { jQuery.event.add(dest, type, events[type][i]); } } } } // 2. Copy user data if (dataUser.hasData(src)) { udataOld = dataUser.access(src); udataCur = jQuery.extend({}, udataOld); dataUser.set(dest, udataCur); } } // Fix IE bugs, see support tests function fixInput(src, dest) { var nodeName = dest.nodeName.toLowerCase(); // Fails to persist the checked state of a cloned checkbox or radio button. if (nodeName === "input" && rcheckableType.test(src.type)) { dest.checked = src.checked; // Fails to return the selected option to the default selected state when cloning options } else if (nodeName === "input" || nodeName === "textarea") { dest.defaultValue = src.defaultValue; } } function domManip(collection, args, callback, ignored) { // Flatten any nested arrays args = concat.apply([], args); var fragment, first, scripts, hasScripts, node, doc, i = 0, l = collection.length, iNoClone = l - 1, value = args[0], valueIsFunction = isFunction(value); // We can't cloneNode fragments that contain checked, in WebKit if (valueIsFunction || l > 1 && typeof value === "string" && !support.checkClone && rchecked.test(value)) { return collection.each(function (index) { var self = collection.eq(index); if (valueIsFunction) { args[0] = value.call(this, index, self.html()); } domManip(self, args, callback, ignored); }); } if (l) { fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored); first = fragment.firstChild; if (fragment.childNodes.length === 1) { fragment = first; } // Require either new content or an interest in ignored elements to invoke the callback if (first || ignored) { scripts = jQuery.map(getAll(fragment, "script"), disableScript); hasScripts = scripts.length; // Use the original fragment for the last item // instead of the first because it can end up // being emptied incorrectly in certain situations (#8070). for (; i < l; i++) { node = fragment; if (i !== iNoClone) { node = jQuery.clone(node, true, true); // Keep references to cloned scripts for later restoration if (hasScripts) { // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge(scripts, getAll(node, "script")); } } callback.call(collection[i], node, i); } if (hasScripts) { doc = scripts[scripts.length - 1].ownerDocument; // Reenable scripts jQuery.map(scripts, restoreScript); // Evaluate executable scripts on first document insertion for (i = 0; i < hasScripts; i++) { node = scripts[i]; if (rscriptType.test(node.type || "") && !dataPriv.access(node, "globalEval") && jQuery.contains(doc, node)) { if (node.src && (node.type || "").toLowerCase() !== "module") { // Optional AJAX dependency, but won't run scripts if not present if (jQuery._evalUrl) { jQuery._evalUrl(node.src); } } else { DOMEval(node.textContent.replace(rcleanScript, ""), doc, node); } } } } } } return collection; } function _remove(elem, selector, keepData) { var node, nodes = selector ? jQuery.filter(selector, elem) : elem, i = 0; for (; (node = nodes[i]) != null; i++) { if (!keepData && node.nodeType === 1) { jQuery.cleanData(getAll(node)); } if (node.parentNode) { if (keepData && jQuery.contains(node.ownerDocument, node)) { setGlobalEval(getAll(node, "script")); } node.parentNode.removeChild(node); } } return elem; } jQuery.extend({ htmlPrefilter: function htmlPrefilter(html) { return html.replace(rxhtmlTag, "<$1>"); }, clone: function clone(elem, dataAndEvents, deepDataAndEvents) { var i, l, srcElements, destElements, clone = elem.cloneNode(true), inPage = jQuery.contains(elem.ownerDocument, elem); // Fix IE cloning issues if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem)) { // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 destElements = getAll(clone); srcElements = getAll(elem); for (i = 0, l = srcElements.length; i < l; i++) { fixInput(srcElements[i], destElements[i]); } } // Copy the events from the original to the clone if (dataAndEvents) { if (deepDataAndEvents) { srcElements = srcElements || getAll(elem); destElements = destElements || getAll(clone); for (i = 0, l = srcElements.length; i < l; i++) { cloneCopyEvent(srcElements[i], destElements[i]); } } else { cloneCopyEvent(elem, clone); } } // Preserve script evaluation history destElements = getAll(clone, "script"); if (destElements.length > 0) { setGlobalEval(destElements, !inPage && getAll(elem, "script")); } // Return the cloned set return clone; }, cleanData: function cleanData(elems) { var data, elem, type, special = jQuery.event.special, i = 0; for (; (elem = elems[i]) !== undefined; i++) { if (acceptData(elem)) { if (data = elem[dataPriv.expando]) { if (data.events) { for (type in data.events) { if (special[type]) { jQuery.event.remove(elem, type); // This is a shortcut to avoid jQuery.event.remove's overhead } else { jQuery.removeEvent(elem, type, data.handle); } } } // Support: Chrome <=35 - 45+ // Assign undefined instead of using delete, see Data#remove elem[dataPriv.expando] = undefined; } if (elem[dataUser.expando]) { // Support: Chrome <=35 - 45+ // Assign undefined instead of using delete, see Data#remove elem[dataUser.expando] = undefined; } } } } }); jQuery.fn.extend({ detach: function detach(selector) { return _remove(this, selector, true); }, remove: function remove(selector) { return _remove(this, selector); }, text: function text(value) { return access(this, function (value) { return value === undefined ? jQuery.text(this) : this.empty().each(function () { if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { this.textContent = value; } }); }, null, value, arguments.length); }, append: function append() { return domManip(this, arguments, function (elem) { if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { var target = manipulationTarget(this, elem); target.appendChild(elem); } }); }, prepend: function prepend() { return domManip(this, arguments, function (elem) { if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { var target = manipulationTarget(this, elem); target.insertBefore(elem, target.firstChild); } }); }, before: function before() { return domManip(this, arguments, function (elem) { if (this.parentNode) { this.parentNode.insertBefore(elem, this); } }); }, after: function after() { return domManip(this, arguments, function (elem) { if (this.parentNode) { this.parentNode.insertBefore(elem, this.nextSibling); } }); }, empty: function empty() { var elem, i = 0; for (; (elem = this[i]) != null; i++) { if (elem.nodeType === 1) { // Prevent memory leaks jQuery.cleanData(getAll(elem, false)); // Remove any remaining nodes elem.textContent = ""; } } return this; }, clone: function clone(dataAndEvents, deepDataAndEvents) { dataAndEvents = dataAndEvents == null ? false : dataAndEvents; deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; return this.map(function () { return jQuery.clone(this, dataAndEvents, deepDataAndEvents); }); }, html: function html(value) { return access(this, function (value) { var elem = this[0] || {}, i = 0, l = this.length; if (value === undefined && elem.nodeType === 1) { return elem.innerHTML; } // See if we can take a shortcut and just use innerHTML if (typeof value === "string" && !rnoInnerhtml.test(value) && !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) { value = jQuery.htmlPrefilter(value); try { for (; i < l; i++) { elem = this[i] || {}; // Remove element nodes and prevent memory leaks if (elem.nodeType === 1) { jQuery.cleanData(getAll(elem, false)); elem.innerHTML = value; } } elem = 0; // If using innerHTML throws an exception, use the fallback method } catch (e) {} } if (elem) { this.empty().append(value); } }, null, value, arguments.length); }, replaceWith: function replaceWith() { var ignored = []; // Make the changes, replacing each non-ignored context element with the new content return domManip(this, arguments, function (elem) { var parent = this.parentNode; if (jQuery.inArray(this, ignored) < 0) { jQuery.cleanData(getAll(this)); if (parent) { parent.replaceChild(elem, this); } } // Force callback invocation }, ignored); } }); jQuery.each({ appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" }, function (name, original) { jQuery.fn[name] = function (selector) { var elems, ret = [], insert = jQuery(selector), last = insert.length - 1, i = 0; for (; i <= last; i++) { elems = i === last ? this : this.clone(true); jQuery(insert[i])[original](elems); // Support: Android <=4.0 only, PhantomJS 1 only // .get() because push.apply(_, arraylike) throws on ancient WebKit push.apply(ret, elems.get()); } return this.pushStack(ret); }; }); var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i"); var getStyles = function getStyles(elem) { // Support: IE <=11 only, Firefox <=30 (#15098, #14150) // IE throws on elements created in popups // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" var view = elem.ownerDocument.defaultView; if (!view || !view.opener) { view = window; } return view.getComputedStyle(elem); }; var rboxStyle = new RegExp(cssExpand.join("|"), "i"); (function () { // Executing both pixelPosition & boxSizingReliable tests require only one layout // so they're executed at the same time to save the second computation. function computeStyleTests() { // This is a singleton, we need to execute it only once if (!div) { return; } container.style.cssText = "position:absolute;left:-11111px;width:60px;" + "margin-top:1px;padding:0;border:0"; div.style.cssText = "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + "margin:auto;border:1px;padding:1px;" + "width:60%;top:1%"; documentElement.appendChild(container).appendChild(div); var divStyle = window.getComputedStyle(div); pixelPositionVal = divStyle.top !== "1%"; // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 reliableMarginLeftVal = roundPixelMeasures(divStyle.marginLeft) === 12; // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 // Some styles come back with percentage values, even though they shouldn't div.style.right = "60%"; pixelBoxStylesVal = roundPixelMeasures(divStyle.right) === 36; // Support: IE 9 - 11 only // Detect misreporting of content dimensions for box-sizing:border-box elements boxSizingReliableVal = roundPixelMeasures(divStyle.width) === 36; // Support: IE 9 only // Detect overflow:scroll screwiness (gh-3699) div.style.position = "absolute"; scrollboxSizeVal = div.offsetWidth === 36 || "absolute"; documentElement.removeChild(container); // Nullify the div so it wouldn't be stored in the memory and // it will also be a sign that checks already performed div = null; } function roundPixelMeasures(measure) { return Math.round(parseFloat(measure)); } var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, reliableMarginLeftVal, container = document.createElement("div"), div = document.createElement("div"); // Finish early in limited (non-browser) environments if (!div.style) { return; } // Support: IE <=9 - 11 only // Style of cloned element affects source element cloned (#8908) div.style.backgroundClip = "content-box"; div.cloneNode(true).style.backgroundClip = ""; support.clearCloneStyle = div.style.backgroundClip === "content-box"; jQuery.extend(support, { boxSizingReliable: function boxSizingReliable() { computeStyleTests(); return boxSizingReliableVal; }, pixelBoxStyles: function pixelBoxStyles() { computeStyleTests(); return pixelBoxStylesVal; }, pixelPosition: function pixelPosition() { computeStyleTests(); return pixelPositionVal; }, reliableMarginLeft: function reliableMarginLeft() { computeStyleTests(); return reliableMarginLeftVal; }, scrollboxSize: function scrollboxSize() { computeStyleTests(); return scrollboxSizeVal; } }); })(); function curCSS(elem, name, computed) { var width, minWidth, maxWidth, ret, // Support: Firefox 51+ // Retrieving style before computed somehow // fixes an issue with getting wrong values // on detached elements style = elem.style; computed = computed || getStyles(elem); // getPropertyValue is needed for: // .css('filter') (IE 9 only, #12537) // .css('--customProperty) (#3144) if (computed) { ret = computed.getPropertyValue(name) || computed[name]; if (ret === "" && !jQuery.contains(elem.ownerDocument, elem)) { ret = jQuery.style(elem, name); } // A tribute to the "awesome hack by Dean Edwards" // Android Browser returns percentage for some values, // but width seems to be reliably pixels. // This is against the CSSOM draft spec: // https://drafts.csswg.org/cssom/#resolved-values if (!support.pixelBoxStyles() && rnumnonpx.test(ret) && rboxStyle.test(name)) { // Remember the original values width = style.width; minWidth = style.minWidth; maxWidth = style.maxWidth; // Put in the new values to get a computed value out style.minWidth = style.maxWidth = style.width = ret; ret = computed.width; // Revert the changed values style.width = width; style.minWidth = minWidth; style.maxWidth = maxWidth; } } return ret !== undefined ? // Support: IE <=9 - 11 only // IE returns zIndex value as an integer. ret + "" : ret; } function addGetHookIf(conditionFn, hookFn) { // Define the hook, we'll check on the first run if it's really needed. return { get: function get() { if (conditionFn()) { // Hook not needed (or it's not possible to use it due // to missing dependency), remove it. delete this.get; return; } // Hook needed; redefine it so that the support test is not executed again. return (this.get = hookFn).apply(this, arguments); } }; } var // Swappable if display is none or starts with table // except "table", "table-cell", or "table-caption" // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display rdisplayswap = /^(none|table(?!-c[ea]).+)/, rcustomProp = /^--/, cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssNormalTransform = { letterSpacing: "0", fontWeight: "400" }, cssPrefixes = ["Webkit", "Moz", "ms"], emptyStyle = document.createElement("div").style; // Return a css property mapped to a potentially vendor prefixed property function vendorPropName(name) { // Shortcut for names that are not vendor prefixed if (name in emptyStyle) { return name; } // Check for vendor prefixed names var capName = name[0].toUpperCase() + name.slice(1), i = cssPrefixes.length; while (i--) { name = cssPrefixes[i] + capName; if (name in emptyStyle) { return name; } } } // Return a property mapped along what jQuery.cssProps suggests or to // a vendor prefixed property. function finalPropName(name) { var ret = jQuery.cssProps[name]; if (!ret) { ret = jQuery.cssProps[name] = vendorPropName(name) || name; } return ret; } function setPositiveNumber(elem, value, subtract) { // Any relative (+/-) values have already been // normalized at this point var matches = rcssNum.exec(value); return matches ? // Guard against undefined "subtract", e.g., when used as in cssHooks Math.max(0, matches[2] - (subtract || 0)) + (matches[3] || "px") : value; } function boxModelAdjustment(elem, dimension, box, isBorderBox, styles, computedVal) { var i = dimension === "width" ? 1 : 0, extra = 0, delta = 0; // Adjustment may not be necessary if (box === (isBorderBox ? "border" : "content")) { return 0; } for (; i < 4; i += 2) { // Both box models exclude margin if (box === "margin") { delta += jQuery.css(elem, box + cssExpand[i], true, styles); } // If we get here with a content-box, we're seeking "padding" or "border" or "margin" if (!isBorderBox) { // Add padding delta += jQuery.css(elem, "padding" + cssExpand[i], true, styles); // For "border" or "margin", add border if (box !== "padding") { delta += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); // But still keep track of it otherwise } else { extra += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); } // If we get here with a border-box (content + padding + border), we're seeking "content" or // "padding" or "margin" } else { // For "content", subtract padding if (box === "content") { delta -= jQuery.css(elem, "padding" + cssExpand[i], true, styles); } // For "content" or "padding", subtract border if (box !== "margin") { delta -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); } } } // Account for positive content-box scroll gutter when requested by providing computedVal if (!isBorderBox && computedVal >= 0) { // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border // Assuming integer scroll gutter, subtract the rest and round down delta += Math.max(0, Math.ceil(elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - computedVal - delta - extra - 0.5)); } return delta; } function getWidthOrHeight(elem, dimension, extra) { // Start with computed style var styles = getStyles(elem), val = curCSS(elem, dimension, styles), isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box", valueIsBorderBox = isBorderBox; // Support: Firefox <=54 // Return a confounding non-pixel value or feign ignorance, as appropriate. if (rnumnonpx.test(val)) { if (!extra) { return val; } val = "auto"; } // Check for style in case a browser which returns unreliable values // for getComputedStyle silently falls back to the reliable elem.style valueIsBorderBox = valueIsBorderBox && (support.boxSizingReliable() || val === elem.style[dimension]); // Fall back to offsetWidth/offsetHeight when value is "auto" // This happens for inline elements with no explicit setting (gh-3571) // Support: Android <=4.1 - 4.3 only // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) if (val === "auto" || !parseFloat(val) && jQuery.css(elem, "display", false, styles) === "inline") { val = elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)]; // offsetWidth/offsetHeight provide border-box values valueIsBorderBox = true; } // Normalize "" and auto val = parseFloat(val) || 0; // Adjust for the element's box model return val + boxModelAdjustment(elem, dimension, extra || (isBorderBox ? "border" : "content"), valueIsBorderBox, styles, // Provide the current computed size to request scroll gutter calculation (gh-3589) val) + "px"; } jQuery.extend({ // Add in style property hooks for overriding the default // behavior of getting and setting a style property cssHooks: { opacity: { get: function get(elem, computed) { if (computed) { // We should always get a number back from opacity var ret = curCSS(elem, "opacity"); return ret === "" ? "1" : ret; } } } }, // Don't automatically add "px" to these possibly-unitless properties cssNumber: { "animationIterationCount": true, "columnCount": true, "fillOpacity": true, "flexGrow": true, "flexShrink": true, "fontWeight": true, "lineHeight": true, "opacity": true, "order": true, "orphans": true, "widows": true, "zIndex": true, "zoom": true }, // Add in properties whose names you wish to fix before // setting or getting the value cssProps: {}, // Get and set the style property on a DOM Node style: function style(elem, name, value, extra) { // Don't set styles on text and comment nodes if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) { return; } // Make sure that we're working with the right name var ret, type, hooks, origName = camelCase(name), isCustomProp = rcustomProp.test(name), style = elem.style; // Make sure that we're working with the right name. We don't // want to query the value if it is a CSS custom property // since they are user-defined. if (!isCustomProp) { name = finalPropName(origName); } // Gets hook for the prefixed version, then unprefixed version hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; // Check if we're setting a value if (value !== undefined) { type = typeof value === "undefined" ? "undefined" : _typeof(value); // Convert "+=" or "-=" to relative numbers (#7345) if (type === "string" && (ret = rcssNum.exec(value)) && ret[1]) { value = adjustCSS(elem, name, ret); // Fixes bug #9237 type = "number"; } // Make sure that null and NaN values aren't set (#7116) if (value == null || value !== value) { return; } // If a number was passed in, add the unit (except for certain CSS properties) if (type === "number") { value += ret && ret[3] || (jQuery.cssNumber[origName] ? "" : "px"); } // background-* props affect original clone's values if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) { style[name] = "inherit"; } // If a hook was provided, use that value, otherwise just set the specified value if (!hooks || !("set" in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) { if (isCustomProp) { style.setProperty(name, value); } else { style[name] = value; } } } else { // If a hook was provided get the non-computed value from there if (hooks && "get" in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) { return ret; } // Otherwise just get the value from the style object return style[name]; } }, css: function css(elem, name, extra, styles) { var val, num, hooks, origName = camelCase(name), isCustomProp = rcustomProp.test(name); // Make sure that we're working with the right name. We don't // want to modify the value if it is a CSS custom property // since they are user-defined. if (!isCustomProp) { name = finalPropName(origName); } // Try prefixed name followed by the unprefixed name hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; // If a hook was provided get the computed value from there if (hooks && "get" in hooks) { val = hooks.get(elem, true, extra); } // Otherwise, if a way to get the computed value exists, use that if (val === undefined) { val = curCSS(elem, name, styles); } // Convert "normal" to computed value if (val === "normal" && name in cssNormalTransform) { val = cssNormalTransform[name]; } // Make numeric if forced or a qualifier was provided and val looks numeric if (extra === "" || extra) { num = parseFloat(val); return extra === true || isFinite(num) ? num || 0 : val; } return val; } }); jQuery.each(["height", "width"], function (i, dimension) { jQuery.cssHooks[dimension] = { get: function get(elem, computed, extra) { if (computed) { // Certain elements can have dimension info if we invisibly show them // but it must have a current display style that would benefit return rdisplayswap.test(jQuery.css(elem, "display")) && ( // Support: Safari 8+ // Table columns in Safari have non-zero offsetWidth & zero // getBoundingClientRect().width unless display is changed. // Support: IE <=11 only // Running getBoundingClientRect on a disconnected node // in IE throws an error. !elem.getClientRects().length || !elem.getBoundingClientRect().width) ? swap(elem, cssShow, function () { return getWidthOrHeight(elem, dimension, extra); }) : getWidthOrHeight(elem, dimension, extra); } }, set: function set(elem, value, extra) { var matches, styles = getStyles(elem), isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box", subtract = extra && boxModelAdjustment(elem, dimension, extra, isBorderBox, styles); // Account for unreliable border-box dimensions by comparing offset* to computed and // faking a content-box to get border and padding (gh-3699) if (isBorderBox && support.scrollboxSize() === styles.position) { subtract -= Math.ceil(elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - parseFloat(styles[dimension]) - boxModelAdjustment(elem, dimension, "border", false, styles) - 0.5); } // Convert to pixels if value adjustment is needed if (subtract && (matches = rcssNum.exec(value)) && (matches[3] || "px") !== "px") { elem.style[dimension] = value; value = jQuery.css(elem, dimension); } return setPositiveNumber(elem, value, subtract); } }; }); jQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft, function (elem, computed) { if (computed) { return (parseFloat(curCSS(elem, "marginLeft")) || elem.getBoundingClientRect().left - swap(elem, { marginLeft: 0 }, function () { return elem.getBoundingClientRect().left; })) + "px"; } }); // These hooks are used by animate to expand properties jQuery.each({ margin: "", padding: "", border: "Width" }, function (prefix, suffix) { jQuery.cssHooks[prefix + suffix] = { expand: function expand(value) { var i = 0, expanded = {}, // Assumes a single number if not a string parts = typeof value === "string" ? value.split(" ") : [value]; for (; i < 4; i++) { expanded[prefix + cssExpand[i] + suffix] = parts[i] || parts[i - 2] || parts[0]; } return expanded; } }; if (prefix !== "margin") { jQuery.cssHooks[prefix + suffix].set = setPositiveNumber; } }); jQuery.fn.extend({ css: function css(name, value) { return access(this, function (elem, name, value) { var styles, len, map = {}, i = 0; if (Array.isArray(name)) { styles = getStyles(elem); len = name.length; for (; i < len; i++) { map[name[i]] = jQuery.css(elem, name[i], false, styles); } return map; } return value !== undefined ? jQuery.style(elem, name, value) : jQuery.css(elem, name); }, name, value, arguments.length > 1); } }); function Tween(elem, options, prop, end, easing) { return new Tween.prototype.init(elem, options, prop, end, easing); } jQuery.Tween = Tween; Tween.prototype = { constructor: Tween, init: function init(elem, options, prop, end, easing, unit) { this.elem = elem; this.prop = prop; this.easing = easing || jQuery.easing._default; this.options = options; this.start = this.now = this.cur(); this.end = end; this.unit = unit || (jQuery.cssNumber[prop] ? "" : "px"); }, cur: function cur() { var hooks = Tween.propHooks[this.prop]; return hooks && hooks.get ? hooks.get(this) : Tween.propHooks._default.get(this); }, run: function run(percent) { var eased, hooks = Tween.propHooks[this.prop]; if (this.options.duration) { this.pos = eased = jQuery.easing[this.easing](percent, this.options.duration * percent, 0, 1, this.options.duration); } else { this.pos = eased = percent; } this.now = (this.end - this.start) * eased + this.start; if (this.options.step) { this.options.step.call(this.elem, this.now, this); } if (hooks && hooks.set) { hooks.set(this); } else { Tween.propHooks._default.set(this); } return this; } }; Tween.prototype.init.prototype = Tween.prototype; Tween.propHooks = { _default: { get: function get(tween) { var result; // Use a property on the element directly when it is not a DOM element, // or when there is no matching style property that exists. if (tween.elem.nodeType !== 1 || tween.elem[tween.prop] != null && tween.elem.style[tween.prop] == null) { return tween.elem[tween.prop]; } // Passing an empty string as a 3rd parameter to .css will automatically // attempt a parseFloat and fallback to a string if the parse fails. // Simple values such as "10px" are parsed to Float; // complex values such as "rotate(1rad)" are returned as-is. result = jQuery.css(tween.elem, tween.prop, ""); // Empty strings, null, undefined and "auto" are converted to 0. return !result || result === "auto" ? 0 : result; }, set: function set(tween) { // Use step hook for back compat. // Use cssHook if its there. // Use .style if available and use plain properties where available. if (jQuery.fx.step[tween.prop]) { jQuery.fx.step[tween.prop](tween); } else if (tween.elem.nodeType === 1 && (tween.elem.style[jQuery.cssProps[tween.prop]] != null || jQuery.cssHooks[tween.prop])) { jQuery.style(tween.elem, tween.prop, tween.now + tween.unit); } else { tween.elem[tween.prop] = tween.now; } } } }; // Support: IE <=9 only // Panic based approach to setting things on disconnected nodes Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { set: function set(tween) { if (tween.elem.nodeType && tween.elem.parentNode) { tween.elem[tween.prop] = tween.now; } } }; jQuery.easing = { linear: function linear(p) { return p; }, swing: function swing(p) { return 0.5 - Math.cos(p * Math.PI) / 2; }, _default: "swing" }; jQuery.fx = Tween.prototype.init; // Back compat <1.8 extension point jQuery.fx.step = {}; var fxNow, inProgress, rfxtypes = /^(?:toggle|show|hide)$/, rrun = /queueHooks$/; function schedule() { if (inProgress) { if (document.hidden === false && window.requestAnimationFrame) { window.requestAnimationFrame(schedule); } else { window.setTimeout(schedule, jQuery.fx.interval); } jQuery.fx.tick(); } } // Animations created synchronously will run synchronously function createFxNow() { window.setTimeout(function () { fxNow = undefined; }); return fxNow = Date.now(); } // Generate parameters to create a standard animation function genFx(type, includeWidth) { var which, i = 0, attrs = { height: type }; // If we include width, step value is 1 to do all cssExpand values, // otherwise step value is 2 to skip over Left and Right includeWidth = includeWidth ? 1 : 0; for (; i < 4; i += 2 - includeWidth) { which = cssExpand[i]; attrs["margin" + which] = attrs["padding" + which] = type; } if (includeWidth) { attrs.opacity = attrs.width = type; } return attrs; } function createTween(value, prop, animation) { var tween, collection = (Animation.tweeners[prop] || []).concat(Animation.tweeners["*"]), index = 0, length = collection.length; for (; index < length; index++) { if (tween = collection[index].call(animation, prop, value)) { // We're done with this property return tween; } } } function defaultPrefilter(elem, props, opts) { var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, isBox = "width" in props || "height" in props, anim = this, orig = {}, style = elem.style, hidden = elem.nodeType && isHiddenWithinTree(elem), dataShow = dataPriv.get(elem, "fxshow"); // Queue-skipping animations hijack the fx hooks if (!opts.queue) { hooks = jQuery._queueHooks(elem, "fx"); if (hooks.unqueued == null) { hooks.unqueued = 0; oldfire = hooks.empty.fire; hooks.empty.fire = function () { if (!hooks.unqueued) { oldfire(); } }; } hooks.unqueued++; anim.always(function () { // Ensure the complete handler is called before this completes anim.always(function () { hooks.unqueued--; if (!jQuery.queue(elem, "fx").length) { hooks.empty.fire(); } }); }); } // Detect show/hide animations for (prop in props) { value = props[prop]; if (rfxtypes.test(value)) { delete props[prop]; toggle = toggle || value === "toggle"; if (value === (hidden ? "hide" : "show")) { // Pretend to be hidden if this is a "show" and // there is still data from a stopped show/hide if (value === "show" && dataShow && dataShow[prop] !== undefined) { hidden = true; // Ignore all other no-op show/hide data } else { continue; } } orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop); } } // Bail out if this is a no-op like .hide().hide() propTween = !jQuery.isEmptyObject(props); if (!propTween && jQuery.isEmptyObject(orig)) { return; } // Restrict "overflow" and "display" styles during box animations if (isBox && elem.nodeType === 1) { // Support: IE <=9 - 11, Edge 12 - 15 // Record all 3 overflow attributes because IE does not infer the shorthand // from identically-valued overflowX and overflowY and Edge just mirrors // the overflowX value there. opts.overflow = [style.overflow, style.overflowX, style.overflowY]; // Identify a display type, preferring old show/hide data over the CSS cascade restoreDisplay = dataShow && dataShow.display; if (restoreDisplay == null) { restoreDisplay = dataPriv.get(elem, "display"); } display = jQuery.css(elem, "display"); if (display === "none") { if (restoreDisplay) { display = restoreDisplay; } else { // Get nonempty value(s) by temporarily forcing visibility showHide([elem], true); restoreDisplay = elem.style.display || restoreDisplay; display = jQuery.css(elem, "display"); showHide([elem]); } } // Animate inline elements as inline-block if (display === "inline" || display === "inline-block" && restoreDisplay != null) { if (jQuery.css(elem, "float") === "none") { // Restore the original display value at the end of pure show/hide animations if (!propTween) { anim.done(function () { style.display = restoreDisplay; }); if (restoreDisplay == null) { display = style.display; restoreDisplay = display === "none" ? "" : display; } } style.display = "inline-block"; } } } if (opts.overflow) { style.overflow = "hidden"; anim.always(function () { style.overflow = opts.overflow[0]; style.overflowX = opts.overflow[1]; style.overflowY = opts.overflow[2]; }); } // Implement show/hide animations propTween = false; for (prop in orig) { // General show/hide setup for this element animation if (!propTween) { if (dataShow) { if ("hidden" in dataShow) { hidden = dataShow.hidden; } } else { dataShow = dataPriv.access(elem, "fxshow", { display: restoreDisplay }); } // Store hidden/visible for toggle so `.stop().toggle()` "reverses" if (toggle) { dataShow.hidden = !hidden; } // Show elements before animating them if (hidden) { showHide([elem], true); } /* eslint-disable no-loop-func */ anim.done(function () { /* eslint-enable no-loop-func */ // The final step of a "hide" animation is actually hiding the element if (!hidden) { showHide([elem]); } dataPriv.remove(elem, "fxshow"); for (prop in orig) { jQuery.style(elem, prop, orig[prop]); } }); } // Per-property setup propTween = createTween(hidden ? dataShow[prop] : 0, prop, anim); if (!(prop in dataShow)) { dataShow[prop] = propTween.start; if (hidden) { propTween.end = propTween.start; propTween.start = 0; } } } } function propFilter(props, specialEasing) { var index, name, easing, value, hooks; // camelCase, specialEasing and expand cssHook pass for (index in props) { name = camelCase(index); easing = specialEasing[name]; value = props[index]; if (Array.isArray(value)) { easing = value[1]; value = props[index] = value[0]; } if (index !== name) { props[name] = value; delete props[index]; } hooks = jQuery.cssHooks[name]; if (hooks && "expand" in hooks) { value = hooks.expand(value); delete props[name]; // Not quite $.extend, this won't overwrite existing keys. // Reusing 'index' because we have the correct "name" for (index in value) { if (!(index in props)) { props[index] = value[index]; specialEasing[index] = easing; } } } else { specialEasing[name] = easing; } } } function Animation(elem, properties, options) { var result, stopped, index = 0, length = Animation.prefilters.length, deferred = jQuery.Deferred().always(function () { // Don't match elem in the :animated selector delete tick.elem; }), tick = function tick() { if (stopped) { return false; } var currentTime = fxNow || createFxNow(), remaining = Math.max(0, animation.startTime + animation.duration - currentTime), // Support: Android 2.3 only // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) temp = remaining / animation.duration || 0, percent = 1 - temp, index = 0, length = animation.tweens.length; for (; index < length; index++) { animation.tweens[index].run(percent); } deferred.notifyWith(elem, [animation, percent, remaining]); // If there's more to do, yield if (percent < 1 && length) { return remaining; } // If this was an empty animation, synthesize a final progress notification if (!length) { deferred.notifyWith(elem, [animation, 1, 0]); } // Resolve the animation and report its conclusion deferred.resolveWith(elem, [animation]); return false; }, animation = deferred.promise({ elem: elem, props: jQuery.extend({}, properties), opts: jQuery.extend(true, { specialEasing: {}, easing: jQuery.easing._default }, options), originalProperties: properties, originalOptions: options, startTime: fxNow || createFxNow(), duration: options.duration, tweens: [], createTween: function createTween(prop, end) { var tween = jQuery.Tween(elem, animation.opts, prop, end, animation.opts.specialEasing[prop] || animation.opts.easing); animation.tweens.push(tween); return tween; }, stop: function stop(gotoEnd) { var index = 0, // If we are going to the end, we want to run all the tweens // otherwise we skip this part length = gotoEnd ? animation.tweens.length : 0; if (stopped) { return this; } stopped = true; for (; index < length; index++) { animation.tweens[index].run(1); } // Resolve when we played the last frame; otherwise, reject if (gotoEnd) { deferred.notifyWith(elem, [animation, 1, 0]); deferred.resolveWith(elem, [animation, gotoEnd]); } else { deferred.rejectWith(elem, [animation, gotoEnd]); } return this; } }), props = animation.props; propFilter(props, animation.opts.specialEasing); for (; index < length; index++) { result = Animation.prefilters[index].call(animation, elem, props, animation.opts); if (result) { if (isFunction(result.stop)) { jQuery._queueHooks(animation.elem, animation.opts.queue).stop = result.stop.bind(result); } return result; } } jQuery.map(props, createTween, animation); if (isFunction(animation.opts.start)) { animation.opts.start.call(elem, animation); } // Attach callbacks from options animation.progress(animation.opts.progress).done(animation.opts.done, animation.opts.complete).fail(animation.opts.fail).always(animation.opts.always); jQuery.fx.timer(jQuery.extend(tick, { elem: elem, anim: animation, queue: animation.opts.queue })); return animation; } jQuery.Animation = jQuery.extend(Animation, { tweeners: { "*": [function (prop, value) { var tween = this.createTween(prop, value); adjustCSS(tween.elem, prop, rcssNum.exec(value), tween); return tween; }] }, tweener: function tweener(props, callback) { if (isFunction(props)) { callback = props; props = ["*"]; } else { props = props.match(rnothtmlwhite); } var prop, index = 0, length = props.length; for (; index < length; index++) { prop = props[index]; Animation.tweeners[prop] = Animation.tweeners[prop] || []; Animation.tweeners[prop].unshift(callback); } }, prefilters: [defaultPrefilter], prefilter: function prefilter(callback, prepend) { if (prepend) { Animation.prefilters.unshift(callback); } else { Animation.prefilters.push(callback); } } }); jQuery.speed = function (speed, easing, fn) { var opt = speed && (typeof speed === "undefined" ? "undefined" : _typeof(speed)) === "object" ? jQuery.extend({}, speed) : { complete: fn || !fn && easing || isFunction(speed) && speed, duration: speed, easing: fn && easing || easing && !isFunction(easing) && easing }; // Go to the end state if fx are off if (jQuery.fx.off) { opt.duration = 0; } else { if (typeof opt.duration !== "number") { if (opt.duration in jQuery.fx.speeds) { opt.duration = jQuery.fx.speeds[opt.duration]; } else { opt.duration = jQuery.fx.speeds._default; } } } // Normalize opt.queue - true/undefined/null -> "fx" if (opt.queue == null || opt.queue === true) { opt.queue = "fx"; } // Queueing opt.old = opt.complete; opt.complete = function () { if (isFunction(opt.old)) { opt.old.call(this); } if (opt.queue) { jQuery.dequeue(this, opt.queue); } }; return opt; }; jQuery.fn.extend({ fadeTo: function fadeTo(speed, to, easing, callback) { // Show any hidden elements after setting opacity to 0 return this.filter(isHiddenWithinTree).css("opacity", 0).show() // Animate to the value specified .end().animate({ opacity: to }, speed, easing, callback); }, animate: function animate(prop, speed, easing, callback) { var empty = jQuery.isEmptyObject(prop), optall = jQuery.speed(speed, easing, callback), doAnimation = function doAnimation() { // Operate on a copy of prop so per-property easing won't be lost var anim = Animation(this, jQuery.extend({}, prop), optall); // Empty animations, or finishing resolves immediately if (empty || dataPriv.get(this, "finish")) { anim.stop(true); } }; doAnimation.finish = doAnimation; return empty || optall.queue === false ? this.each(doAnimation) : this.queue(optall.queue, doAnimation); }, stop: function stop(type, clearQueue, gotoEnd) { var stopQueue = function stopQueue(hooks) { var stop = hooks.stop; delete hooks.stop; stop(gotoEnd); }; if (typeof type !== "string") { gotoEnd = clearQueue; clearQueue = type; type = undefined; } if (clearQueue && type !== false) { this.queue(type || "fx", []); } return this.each(function () { var dequeue = true, index = type != null && type + "queueHooks", timers = jQuery.timers, data = dataPriv.get(this); if (index) { if (data[index] && data[index].stop) { stopQueue(data[index]); } } else { for (index in data) { if (data[index] && data[index].stop && rrun.test(index)) { stopQueue(data[index]); } } } for (index = timers.length; index--;) { if (timers[index].elem === this && (type == null || timers[index].queue === type)) { timers[index].anim.stop(gotoEnd); dequeue = false; timers.splice(index, 1); } } // Start the next in the queue if the last step wasn't forced. // Timers currently will call their complete callbacks, which // will dequeue but only if they were gotoEnd. if (dequeue || !gotoEnd) { jQuery.dequeue(this, type); } }); }, finish: function finish(type) { if (type !== false) { type = type || "fx"; } return this.each(function () { var index, data = dataPriv.get(this), queue = data[type + "queue"], hooks = data[type + "queueHooks"], timers = jQuery.timers, length = queue ? queue.length : 0; // Enable finishing flag on private data data.finish = true; // Empty the queue first jQuery.queue(this, type, []); if (hooks && hooks.stop) { hooks.stop.call(this, true); } // Look for any active animations, and finish them for (index = timers.length; index--;) { if (timers[index].elem === this && timers[index].queue === type) { timers[index].anim.stop(true); timers.splice(index, 1); } } // Look for any animations in the old queue and finish them for (index = 0; index < length; index++) { if (queue[index] && queue[index].finish) { queue[index].finish.call(this); } } // Turn off finishing flag delete data.finish; }); } }); jQuery.each(["toggle", "show", "hide"], function (i, name) { var cssFn = jQuery.fn[name]; jQuery.fn[name] = function (speed, easing, callback) { return speed == null || typeof speed === "boolean" ? cssFn.apply(this, arguments) : this.animate(genFx(name, true), speed, easing, callback); }; }); // Generate shortcuts for custom animations jQuery.each({ slideDown: genFx("show"), slideUp: genFx("hide"), slideToggle: genFx("toggle"), fadeIn: { opacity: "show" }, fadeOut: { opacity: "hide" }, fadeToggle: { opacity: "toggle" } }, function (name, props) { jQuery.fn[name] = function (speed, easing, callback) { return this.animate(props, speed, easing, callback); }; }); jQuery.timers = []; jQuery.fx.tick = function () { var timer, i = 0, timers = jQuery.timers; fxNow = Date.now(); for (; i < timers.length; i++) { timer = timers[i]; // Run the timer and safely remove it when done (allowing for external removal) if (!timer() && timers[i] === timer) { timers.splice(i--, 1); } } if (!timers.length) { jQuery.fx.stop(); } fxNow = undefined; }; jQuery.fx.timer = function (timer) { jQuery.timers.push(timer); jQuery.fx.start(); }; jQuery.fx.interval = 13; jQuery.fx.start = function () { if (inProgress) { return; } inProgress = true; schedule(); }; jQuery.fx.stop = function () { inProgress = null; }; jQuery.fx.speeds = { slow: 600, fast: 200, // Default speed _default: 400 }; // Based off of the plugin by Clint Helfers, with permission. // https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ jQuery.fn.delay = function (time, type) { time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; type = type || "fx"; return this.queue(type, function (next, hooks) { var timeout = window.setTimeout(next, time); hooks.stop = function () { window.clearTimeout(timeout); }; }); }; (function () { var input = document.createElement("input"), select = document.createElement("select"), opt = select.appendChild(document.createElement("option")); input.type = "checkbox"; // Support: Android <=4.3 only // Default value for a checkbox should be "on" support.checkOn = input.value !== ""; // Support: IE <=11 only // Must access selectedIndex to make default options select support.optSelected = opt.selected; // Support: IE <=11 only // An input loses its value after becoming a radio input = document.createElement("input"); input.value = "t"; input.type = "radio"; support.radioValue = input.value === "t"; })(); var boolHook, attrHandle = jQuery.expr.attrHandle; jQuery.fn.extend({ attr: function attr(name, value) { return access(this, jQuery.attr, name, value, arguments.length > 1); }, removeAttr: function removeAttr(name) { return this.each(function () { jQuery.removeAttr(this, name); }); } }); jQuery.extend({ attr: function attr(elem, name, value) { var ret, hooks, nType = elem.nodeType; // Don't get/set attributes on text, comment and attribute nodes if (nType === 3 || nType === 8 || nType === 2) { return; } // Fallback to prop when attributes are not supported if (typeof elem.getAttribute === "undefined") { return jQuery.prop(elem, name, value); } // Attribute hooks are determined by the lowercase version // Grab necessary hook if one is defined if (nType !== 1 || !jQuery.isXMLDoc(elem)) { hooks = jQuery.attrHooks[name.toLowerCase()] || (jQuery.expr.match.bool.test(name) ? boolHook : undefined); } if (value !== undefined) { if (value === null) { jQuery.removeAttr(elem, name); return; } if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) { return ret; } elem.setAttribute(name, value + ""); return value; } if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) { return ret; } ret = jQuery.find.attr(elem, name); // Non-existent attributes return null, we normalize to undefined return ret == null ? undefined : ret; }, attrHooks: { type: { set: function set(elem, value) { if (!support.radioValue && value === "radio" && nodeName(elem, "input")) { var val = elem.value; elem.setAttribute("type", value); if (val) { elem.value = val; } return value; } } } }, removeAttr: function removeAttr(elem, value) { var name, i = 0, // Attribute names can contain non-HTML whitespace characters // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 attrNames = value && value.match(rnothtmlwhite); if (attrNames && elem.nodeType === 1) { while (name = attrNames[i++]) { elem.removeAttribute(name); } } } }); // Hooks for boolean attributes boolHook = { set: function set(elem, value, name) { if (value === false) { // Remove boolean attributes when set to false jQuery.removeAttr(elem, name); } else { elem.setAttribute(name, name); } return name; } }; jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (i, name) { var getter = attrHandle[name] || jQuery.find.attr; attrHandle[name] = function (elem, name, isXML) { var ret, handle, lowercaseName = name.toLowerCase(); if (!isXML) { // Avoid an infinite loop by temporarily removing this function from the getter handle = attrHandle[lowercaseName]; attrHandle[lowercaseName] = ret; ret = getter(elem, name, isXML) != null ? lowercaseName : null; attrHandle[lowercaseName] = handle; } return ret; }; }); var rfocusable = /^(?:input|select|textarea|button)$/i, rclickable = /^(?:a|area)$/i; jQuery.fn.extend({ prop: function prop(name, value) { return access(this, jQuery.prop, name, value, arguments.length > 1); }, removeProp: function removeProp(name) { return this.each(function () { delete this[jQuery.propFix[name] || name]; }); } }); jQuery.extend({ prop: function prop(elem, name, value) { var ret, hooks, nType = elem.nodeType; // Don't get/set properties on text, comment and attribute nodes if (nType === 3 || nType === 8 || nType === 2) { return; } if (nType !== 1 || !jQuery.isXMLDoc(elem)) { // Fix name and attach hooks name = jQuery.propFix[name] || name; hooks = jQuery.propHooks[name]; } if (value !== undefined) { if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) { return ret; } return elem[name] = value; } if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) { return ret; } return elem[name]; }, propHooks: { tabIndex: { get: function get(elem) { // Support: IE <=9 - 11 only // elem.tabIndex doesn't always return the // correct value when it hasn't been explicitly set // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ // Use proper attribute retrieval(#12072) var tabindex = jQuery.find.attr(elem, "tabindex"); if (tabindex) { return parseInt(tabindex, 10); } if (rfocusable.test(elem.nodeName) || rclickable.test(elem.nodeName) && elem.href) { return 0; } return -1; } } }, propFix: { "for": "htmlFor", "class": "className" } }); // Support: IE <=11 only // Accessing the selectedIndex property // forces the browser to respect setting selected // on the option // The getter ensures a default option is selected // when in an optgroup // eslint rule "no-unused-expressions" is disabled for this code // since it considers such accessions noop if (!support.optSelected) { jQuery.propHooks.selected = { get: function get(elem) { /* eslint no-unused-expressions: "off" */ var parent = elem.parentNode; if (parent && parent.parentNode) { parent.parentNode.selectedIndex; } return null; }, set: function set(elem) { /* eslint no-unused-expressions: "off" */ var parent = elem.parentNode; if (parent) { parent.selectedIndex; if (parent.parentNode) { parent.parentNode.selectedIndex; } } } }; } jQuery.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function () { jQuery.propFix[this.toLowerCase()] = this; }); // Strip and collapse whitespace according to HTML spec // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace function stripAndCollapse(value) { var tokens = value.match(rnothtmlwhite) || []; return tokens.join(" "); } function getClass(elem) { return elem.getAttribute && elem.getAttribute("class") || ""; } function classesToArray(value) { if (Array.isArray(value)) { return value; } if (typeof value === "string") { return value.match(rnothtmlwhite) || []; } return []; } jQuery.fn.extend({ addClass: function addClass(value) { var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; if (isFunction(value)) { return this.each(function (j) { jQuery(this).addClass(value.call(this, j, getClass(this))); }); } classes = classesToArray(value); if (classes.length) { while (elem = this[i++]) { curValue = getClass(elem); cur = elem.nodeType === 1 && " " + stripAndCollapse(curValue) + " "; if (cur) { j = 0; while (clazz = classes[j++]) { if (cur.indexOf(" " + clazz + " ") < 0) { cur += clazz + " "; } } // Only assign if different to avoid unneeded rendering. finalValue = stripAndCollapse(cur); if (curValue !== finalValue) { elem.setAttribute("class", finalValue); } } } } return this; }, removeClass: function removeClass(value) { var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; if (isFunction(value)) { return this.each(function (j) { jQuery(this).removeClass(value.call(this, j, getClass(this))); }); } if (!arguments.length) { return this.attr("class", ""); } classes = classesToArray(value); if (classes.length) { while (elem = this[i++]) { curValue = getClass(elem); // This expression is here for better compressibility (see addClass) cur = elem.nodeType === 1 && " " + stripAndCollapse(curValue) + " "; if (cur) { j = 0; while (clazz = classes[j++]) { // Remove *all* instances while (cur.indexOf(" " + clazz + " ") > -1) { cur = cur.replace(" " + clazz + " ", " "); } } // Only assign if different to avoid unneeded rendering. finalValue = stripAndCollapse(cur); if (curValue !== finalValue) { elem.setAttribute("class", finalValue); } } } } return this; }, toggleClass: function toggleClass(value, stateVal) { var type = typeof value === "undefined" ? "undefined" : _typeof(value), isValidValue = type === "string" || Array.isArray(value); if (typeof stateVal === "boolean" && isValidValue) { return stateVal ? this.addClass(value) : this.removeClass(value); } if (isFunction(value)) { return this.each(function (i) { jQuery(this).toggleClass(value.call(this, i, getClass(this), stateVal), stateVal); }); } return this.each(function () { var className, i, self, classNames; if (isValidValue) { // Toggle individual class names i = 0; self = jQuery(this); classNames = classesToArray(value); while (className = classNames[i++]) { // Check each className given, space separated list if (self.hasClass(className)) { self.removeClass(className); } else { self.addClass(className); } } // Toggle whole class name } else if (value === undefined || type === "boolean") { className = getClass(this); if (className) { // Store className if set dataPriv.set(this, "__className__", className); } // If the element has a class name or if we're passed `false`, // then remove the whole classname (if there was one, the above saved it). // Otherwise bring back whatever was previously saved (if anything), // falling back to the empty string if nothing was stored. if (this.setAttribute) { this.setAttribute("class", className || value === false ? "" : dataPriv.get(this, "__className__") || ""); } } }); }, hasClass: function hasClass(selector) { var className, elem, i = 0; className = " " + selector + " "; while (elem = this[i++]) { if (elem.nodeType === 1 && (" " + stripAndCollapse(getClass(elem)) + " ").indexOf(className) > -1) { return true; } } return false; } }); var rreturn = /\r/g; jQuery.fn.extend({ val: function val(value) { var hooks, ret, valueIsFunction, elem = this[0]; if (!arguments.length) { if (elem) { hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()]; if (hooks && "get" in hooks && (ret = hooks.get(elem, "value")) !== undefined) { return ret; } ret = elem.value; // Handle most common string cases if (typeof ret === "string") { return ret.replace(rreturn, ""); } // Handle cases where value is null/undef or number return ret == null ? "" : ret; } return; } valueIsFunction = isFunction(value); return this.each(function (i) { var val; if (this.nodeType !== 1) { return; } if (valueIsFunction) { val = value.call(this, i, jQuery(this).val()); } else { val = value; } // Treat null/undefined as ""; convert numbers to string if (val == null) { val = ""; } else if (typeof val === "number") { val += ""; } else if (Array.isArray(val)) { val = jQuery.map(val, function (value) { return value == null ? "" : value + ""; }); } hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()]; // If set returns undefined, fall back to normal setting if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) { this.value = val; } }); } }); jQuery.extend({ valHooks: { option: { get: function get(elem) { var val = jQuery.find.attr(elem, "value"); return val != null ? val : // Support: IE <=10 - 11 only // option.text throws exceptions (#14686, #14858) // Strip and collapse whitespace // https://html.spec.whatwg.org/#strip-and-collapse-whitespace stripAndCollapse(jQuery.text(elem)); } }, select: { get: function get(elem) { var value, option, i, options = elem.options, index = elem.selectedIndex, one = elem.type === "select-one", values = one ? null : [], max = one ? index + 1 : options.length; if (index < 0) { i = max; } else { i = one ? index : 0; } // Loop through all the selected options for (; i < max; i++) { option = options[i]; // Support: IE <=9 only // IE8-9 doesn't update selected after form reset (#2551) if ((option.selected || i === index) && // Don't return options that are disabled or in a disabled optgroup !option.disabled && (!option.parentNode.disabled || !nodeName(option.parentNode, "optgroup"))) { // Get the specific value for the option value = jQuery(option).val(); // We don't need an array for one selects if (one) { return value; } // Multi-Selects return an array values.push(value); } } return values; }, set: function set(elem, value) { var optionSet, option, options = elem.options, values = jQuery.makeArray(value), i = options.length; while (i--) { option = options[i]; /* eslint-disable no-cond-assign */ if (option.selected = jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1) { optionSet = true; } /* eslint-enable no-cond-assign */ } // Force browsers to behave consistently when non-matching value is set if (!optionSet) { elem.selectedIndex = -1; } return values; } } } }); // Radios and checkboxes getter/setter jQuery.each(["radio", "checkbox"], function () { jQuery.valHooks[this] = { set: function set(elem, value) { if (Array.isArray(value)) { return elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1; } } }; if (!support.checkOn) { jQuery.valHooks[this].get = function (elem) { return elem.getAttribute("value") === null ? "on" : elem.value; }; } }); // Return jQuery for attributes-only inclusion support.focusin = "onfocusin" in window; var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, stopPropagationCallback = function stopPropagationCallback(e) { e.stopPropagation(); }; jQuery.extend(jQuery.event, { trigger: function trigger(event, data, elem, onlyHandlers) { var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, eventPath = [elem || document], type = hasOwn.call(event, "type") ? event.type : event, namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : []; cur = lastElement = tmp = elem = elem || document; // Don't do events on text and comment nodes if (elem.nodeType === 3 || elem.nodeType === 8) { return; } // focus/blur morphs to focusin/out; ensure we're not firing them right now if (rfocusMorph.test(type + jQuery.event.triggered)) { return; } if (type.indexOf(".") > -1) { // Namespaced trigger; create a regexp to match event type in handle() namespaces = type.split("."); type = namespaces.shift(); namespaces.sort(); } ontype = type.indexOf(":") < 0 && "on" + type; // Caller can pass in a jQuery.Event object, Object, or just an event type string event = event[jQuery.expando] ? event : new jQuery.Event(type, (typeof event === "undefined" ? "undefined" : _typeof(event)) === "object" && event); // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) event.isTrigger = onlyHandlers ? 2 : 3; event.namespace = namespaces.join("."); event.rnamespace = event.namespace ? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; // Clean up the event in case it is being reused event.result = undefined; if (!event.target) { event.target = elem; } // Clone any incoming data and prepend the event, creating the handler arg list data = data == null ? [event] : jQuery.makeArray(data, [event]); // Allow special events to draw outside the lines special = jQuery.event.special[type] || {}; if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) { return; } // Determine event propagation path in advance, per W3C events spec (#9951) // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) if (!onlyHandlers && !special.noBubble && !isWindow(elem)) { bubbleType = special.delegateType || type; if (!rfocusMorph.test(bubbleType + type)) { cur = cur.parentNode; } for (; cur; cur = cur.parentNode) { eventPath.push(cur); tmp = cur; } // Only add window if we got to document (e.g., not plain obj or detached DOM) if (tmp === (elem.ownerDocument || document)) { eventPath.push(tmp.defaultView || tmp.parentWindow || window); } } // Fire handlers on the event path i = 0; while ((cur = eventPath[i++]) && !event.isPropagationStopped()) { lastElement = cur; event.type = i > 1 ? bubbleType : special.bindType || type; // jQuery handler handle = (dataPriv.get(cur, "events") || {})[event.type] && dataPriv.get(cur, "handle"); if (handle) { handle.apply(cur, data); } // Native handler handle = ontype && cur[ontype]; if (handle && handle.apply && acceptData(cur)) { event.result = handle.apply(cur, data); if (event.result === false) { event.preventDefault(); } } } event.type = type; // If nobody prevented the default action, do it now if (!onlyHandlers && !event.isDefaultPrevented()) { if ((!special._default || special._default.apply(eventPath.pop(), data) === false) && acceptData(elem)) { // Call a native DOM method on the target with the same name as the event. // Don't do default actions on window, that's where global variables be (#6170) if (ontype && isFunction(elem[type]) && !isWindow(elem)) { // Don't re-trigger an onFOO event when we call its FOO() method tmp = elem[ontype]; if (tmp) { elem[ontype] = null; } // Prevent re-triggering of the same event, since we already bubbled it above jQuery.event.triggered = type; if (event.isPropagationStopped()) { lastElement.addEventListener(type, stopPropagationCallback); } elem[type](); if (event.isPropagationStopped()) { lastElement.removeEventListener(type, stopPropagationCallback); } jQuery.event.triggered = undefined; if (tmp) { elem[ontype] = tmp; } } } } return event.result; }, // Piggyback on a donor event to simulate a different one // Used only for `focus(in | out)` events simulate: function simulate(type, elem, event) { var e = jQuery.extend(new jQuery.Event(), event, { type: type, isSimulated: true }); jQuery.event.trigger(e, null, elem); } }); jQuery.fn.extend({ trigger: function trigger(type, data) { return this.each(function () { jQuery.event.trigger(type, data, this); }); }, triggerHandler: function triggerHandler(type, data) { var elem = this[0]; if (elem) { return jQuery.event.trigger(type, data, elem, true); } } }); // Support: Firefox <=44 // Firefox doesn't have focus(in | out) events // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 // // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 // focus(in | out) events fire after focus & blur events, // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 if (!support.focusin) { jQuery.each({ focus: "focusin", blur: "focusout" }, function (orig, fix) { // Attach a single capturing handler on the document while someone wants focusin/focusout var handler = function handler(event) { jQuery.event.simulate(fix, event.target, jQuery.event.fix(event)); }; jQuery.event.special[fix] = { setup: function setup() { var doc = this.ownerDocument || this, attaches = dataPriv.access(doc, fix); if (!attaches) { doc.addEventListener(orig, handler, true); } dataPriv.access(doc, fix, (attaches || 0) + 1); }, teardown: function teardown() { var doc = this.ownerDocument || this, attaches = dataPriv.access(doc, fix) - 1; if (!attaches) { doc.removeEventListener(orig, handler, true); dataPriv.remove(doc, fix); } else { dataPriv.access(doc, fix, attaches); } } }; }); } var location = window.location; var nonce = Date.now(); var rquery = /\?/; // Cross-browser xml parsing jQuery.parseXML = function (data) { var xml; if (!data || typeof data !== "string") { return null; } // Support: IE 9 - 11 only // IE throws on parseFromString with invalid input. try { xml = new window.DOMParser().parseFromString(data, "text/xml"); } catch (e) { xml = undefined; } if (!xml || xml.getElementsByTagName("parsererror").length) { jQuery.error("Invalid XML: " + data); } return xml; }; var rbracket = /\[\]$/, rCRLF = /\r?\n/g, rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, rsubmittable = /^(?:input|select|textarea|keygen)/i; function buildParams(prefix, obj, traditional, add) { var name; if (Array.isArray(obj)) { // Serialize array item. jQuery.each(obj, function (i, v) { if (traditional || rbracket.test(prefix)) { // Treat each array item as a scalar. add(prefix, v); } else { // Item is non-scalar (array or object), encode its numeric index. buildParams(prefix + "[" + ((typeof v === "undefined" ? "undefined" : _typeof(v)) === "object" && v != null ? i : "") + "]", v, traditional, add); } }); } else if (!traditional && toType(obj) === "object") { // Serialize object item. for (name in obj) { buildParams(prefix + "[" + name + "]", obj[name], traditional, add); } } else { // Serialize scalar item. add(prefix, obj); } } // Serialize an array of form elements or a set of // key/values into a query string jQuery.param = function (a, traditional) { var prefix, s = [], add = function add(key, valueOrFunction) { // If value is a function, invoke it and use its return value var value = isFunction(valueOrFunction) ? valueOrFunction() : valueOrFunction; s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value == null ? "" : value); }; // If an array was passed in, assume that it is an array of form elements. if (Array.isArray(a) || a.jquery && !jQuery.isPlainObject(a)) { // Serialize the form elements jQuery.each(a, function () { add(this.name, this.value); }); } else { // If traditional, encode the "old" way (the way 1.3.2 or older // did it), otherwise encode params recursively. for (prefix in a) { buildParams(prefix, a[prefix], traditional, add); } } // Return the resulting serialization return s.join("&"); }; jQuery.fn.extend({ serialize: function serialize() { return jQuery.param(this.serializeArray()); }, serializeArray: function serializeArray() { return this.map(function () { // Can add propHook for "elements" to filter or add form elements var elements = jQuery.prop(this, "elements"); return elements ? jQuery.makeArray(elements) : this; }).filter(function () { var type = this.type; // Use .is( ":disabled" ) so that fieldset[disabled] works return this.name && !jQuery(this).is(":disabled") && rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && (this.checked || !rcheckableType.test(type)); }).map(function (i, elem) { var val = jQuery(this).val(); if (val == null) { return null; } if (Array.isArray(val)) { return jQuery.map(val, function (val) { return { name: elem.name, value: val.replace(rCRLF, "\r\n") }; }); } return { name: elem.name, value: val.replace(rCRLF, "\r\n") }; }).get(); } }); var r20 = /%20/g, rhash = /#.*$/, rantiCache = /([?&])_=[^&]*/, rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, // #7653, #8125, #8152: local protocol detection rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, /* Prefilters * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) * 2) These are called: * - BEFORE asking for a transport * - AFTER param serialization (s.data is a string if s.processData is true) * 3) key is the dataType * 4) the catchall symbol "*" can be used * 5) execution will start with transport dataType and THEN continue down to "*" if needed */ prefilters = {}, /* Transports bindings * 1) key is the dataType * 2) the catchall symbol "*" can be used * 3) selection will start with transport dataType and THEN go to "*" if needed */ transports = {}, // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression allTypes = "*/".concat("*"), // Anchor tag for parsing the document origin originAnchor = document.createElement("a"); originAnchor.href = location.href; // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport function addToPrefiltersOrTransports(structure) { // dataTypeExpression is optional and defaults to "*" return function (dataTypeExpression, func) { if (typeof dataTypeExpression !== "string") { func = dataTypeExpression; dataTypeExpression = "*"; } var dataType, i = 0, dataTypes = dataTypeExpression.toLowerCase().match(rnothtmlwhite) || []; if (isFunction(func)) { // For each dataType in the dataTypeExpression while (dataType = dataTypes[i++]) { // Prepend if requested if (dataType[0] === "+") { dataType = dataType.slice(1) || "*"; (structure[dataType] = structure[dataType] || []).unshift(func); // Otherwise append } else { (structure[dataType] = structure[dataType] || []).push(func); } } } }; } // Base inspection function for prefilters and transports function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) { var inspected = {}, seekingTransport = structure === transports; function inspect(dataType) { var selected; inspected[dataType] = true; jQuery.each(structure[dataType] || [], function (_, prefilterOrFactory) { var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR); if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) { options.dataTypes.unshift(dataTypeOrTransport); inspect(dataTypeOrTransport); return false; } else if (seekingTransport) { return !(selected = dataTypeOrTransport); } }); return selected; } return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*"); } // A special extend for ajax options // that takes "flat" options (not to be deep extended) // Fixes #9887 function ajaxExtend(target, src) { var key, deep, flatOptions = jQuery.ajaxSettings.flatOptions || {}; for (key in src) { if (src[key] !== undefined) { (flatOptions[key] ? target : deep || (deep = {}))[key] = src[key]; } } if (deep) { jQuery.extend(true, target, deep); } return target; } /* Handles responses to an ajax request: * - finds the right dataType (mediates between content-type and expected dataType) * - returns the corresponding response */ function ajaxHandleResponses(s, jqXHR, responses) { var ct, type, finalDataType, firstDataType, contents = s.contents, dataTypes = s.dataTypes; // Remove auto dataType and get content-type in the process while (dataTypes[0] === "*") { dataTypes.shift(); if (ct === undefined) { ct = s.mimeType || jqXHR.getResponseHeader("Content-Type"); } } // Check if we're dealing with a known content-type if (ct) { for (type in contents) { if (contents[type] && contents[type].test(ct)) { dataTypes.unshift(type); break; } } } // Check to see if we have a response for the expected dataType if (dataTypes[0] in responses) { finalDataType = dataTypes[0]; } else { // Try convertible dataTypes for (type in responses) { if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) { finalDataType = type; break; } if (!firstDataType) { firstDataType = type; } } // Or just use first one finalDataType = finalDataType || firstDataType; } // If we found a dataType // We add the dataType to the list if needed // and return the corresponding response if (finalDataType) { if (finalDataType !== dataTypes[0]) { dataTypes.unshift(finalDataType); } return responses[finalDataType]; } } /* Chain conversions given the request and the original response * Also sets the responseXXX fields on the jqXHR instance */ function ajaxConvert(s, response, jqXHR, isSuccess) { var conv2, current, conv, tmp, prev, converters = {}, // Work with a copy of dataTypes in case we need to modify it for conversion dataTypes = s.dataTypes.slice(); // Create converters map with lowercased keys if (dataTypes[1]) { for (conv in s.converters) { converters[conv.toLowerCase()] = s.converters[conv]; } } current = dataTypes.shift(); // Convert to each sequential dataType while (current) { if (s.responseFields[current]) { jqXHR[s.responseFields[current]] = response; } // Apply the dataFilter if provided if (!prev && isSuccess && s.dataFilter) { response = s.dataFilter(response, s.dataType); } prev = current; current = dataTypes.shift(); if (current) { // There's only work to do if current dataType is non-auto if (current === "*") { current = prev; // Convert response if prev dataType is non-auto and differs from current } else if (prev !== "*" && prev !== current) { // Seek a direct converter conv = converters[prev + " " + current] || converters["* " + current]; // If none found, seek a pair if (!conv) { for (conv2 in converters) { // If conv2 outputs current tmp = conv2.split(" "); if (tmp[1] === current) { // If prev can be converted to accepted input conv = converters[prev + " " + tmp[0]] || converters["* " + tmp[0]]; if (conv) { // Condense equivalence converters if (conv === true) { conv = converters[conv2]; // Otherwise, insert the intermediate dataType } else if (converters[conv2] !== true) { current = tmp[0]; dataTypes.unshift(tmp[1]); } break; } } } } // Apply converter (if not an equivalence) if (conv !== true) { // Unless errors are allowed to bubble, catch and return them if (conv && s.throws) { response = conv(response); } else { try { response = conv(response); } catch (e) { return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; } } } } } } return { state: "success", data: response }; } jQuery.extend({ // Counter for holding the number of active queries active: 0, // Last-Modified header cache for next request lastModified: {}, etag: {}, ajaxSettings: { url: location.href, type: "GET", isLocal: rlocalProtocol.test(location.protocol), global: true, processData: true, async: true, contentType: "application/x-www-form-urlencoded; charset=UTF-8", /* timeout: 0, data: null, dataType: null, username: null, password: null, cache: null, throws: false, traditional: false, headers: {}, */ accepts: { "*": allTypes, text: "text/plain", html: "text/html", xml: "application/xml, text/xml", json: "application/json, text/javascript" }, contents: { xml: /\bxml\b/, html: /\bhtml/, json: /\bjson\b/ }, responseFields: { xml: "responseXML", text: "responseText", json: "responseJSON" }, // Data converters // Keys separate source (or catchall "*") and destination types with a single space converters: { // Convert anything to text "* text": String, // Text to html (true = no transformation) "text html": true, // Evaluate text as a json expression "text json": JSON.parse, // Parse text as xml "text xml": jQuery.parseXML }, // For options that shouldn't be deep extended: // you can add your own custom options here if // and when you create one that shouldn't be // deep extended (see ajaxExtend) flatOptions: { url: true, context: true } }, // Creates a full fledged settings object into target // with both ajaxSettings and settings fields. // If target is omitted, writes into ajaxSettings. ajaxSetup: function ajaxSetup(target, settings) { return settings ? // Building a settings object ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) : // Extending ajaxSettings ajaxExtend(jQuery.ajaxSettings, target); }, ajaxPrefilter: addToPrefiltersOrTransports(prefilters), ajaxTransport: addToPrefiltersOrTransports(transports), // Main method ajax: function ajax(url, options) { // If url is an object, simulate pre-1.5 signature if ((typeof url === "undefined" ? "undefined" : _typeof(url)) === "object") { options = url; url = undefined; } // Force options to be an object options = options || {}; var transport, // URL without anti-cache param cacheURL, // Response headers responseHeadersString, responseHeaders, // timeout handle timeoutTimer, // Url cleanup var urlAnchor, // Request state (becomes false upon send and true upon completion) completed, // To know if global events are to be dispatched fireGlobals, // Loop variable i, // uncached part of the url uncached, // Create the final options object s = jQuery.ajaxSetup({}, options), // Callbacks context callbackContext = s.context || s, // Context for global events is callbackContext if it is a DOM node or jQuery collection globalEventContext = s.context && (callbackContext.nodeType || callbackContext.jquery) ? jQuery(callbackContext) : jQuery.event, // Deferreds deferred = jQuery.Deferred(), completeDeferred = jQuery.Callbacks("once memory"), // Status-dependent callbacks _statusCode = s.statusCode || {}, // Headers (they are sent all at once) requestHeaders = {}, requestHeadersNames = {}, // Default abort message strAbort = "canceled", // Fake xhr jqXHR = { readyState: 0, // Builds headers hashtable if needed getResponseHeader: function getResponseHeader(key) { var match; if (completed) { if (!responseHeaders) { responseHeaders = {}; while (match = rheaders.exec(responseHeadersString)) { responseHeaders[match[1].toLowerCase()] = match[2]; } } match = responseHeaders[key.toLowerCase()]; } return match == null ? null : match; }, // Raw string getAllResponseHeaders: function getAllResponseHeaders() { return completed ? responseHeadersString : null; }, // Caches the header setRequestHeader: function setRequestHeader(name, value) { if (completed == null) { name = requestHeadersNames[name.toLowerCase()] = requestHeadersNames[name.toLowerCase()] || name; requestHeaders[name] = value; } return this; }, // Overrides response content-type header overrideMimeType: function overrideMimeType(type) { if (completed == null) { s.mimeType = type; } return this; }, // Status-dependent callbacks statusCode: function statusCode(map) { var code; if (map) { if (completed) { // Execute the appropriate callbacks jqXHR.always(map[jqXHR.status]); } else { // Lazy-add the new callbacks in a way that preserves old ones for (code in map) { _statusCode[code] = [_statusCode[code], map[code]]; } } } return this; }, // Cancel the request abort: function abort(statusText) { var finalText = statusText || strAbort; if (transport) { transport.abort(finalText); } done(0, finalText); return this; } }; // Attach deferreds deferred.promise(jqXHR); // Add protocol if not provided (prefilters might expect it) // Handle falsy url in the settings object (#10093: consistency with old signature) // We also use the url parameter if available s.url = ((url || s.url || location.href) + "").replace(rprotocol, location.protocol + "//"); // Alias method option to type as per ticket #12004 s.type = options.method || options.type || s.method || s.type; // Extract dataTypes list s.dataTypes = (s.dataType || "*").toLowerCase().match(rnothtmlwhite) || [""]; // A cross-domain request is in order when the origin doesn't match the current origin. if (s.crossDomain == null) { urlAnchor = document.createElement("a"); // Support: IE <=8 - 11, Edge 12 - 15 // IE throws exception on accessing the href property if url is malformed, // e.g. http://example.com:80x/ try { urlAnchor.href = s.url; // Support: IE <=8 - 11 only // Anchor's host property isn't correctly set when s.url is relative urlAnchor.href = urlAnchor.href; s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== urlAnchor.protocol + "//" + urlAnchor.host; } catch (e) { // If there is an error parsing the URL, assume it is crossDomain, // it can be rejected by the transport if it is invalid s.crossDomain = true; } } // Convert data if not already a string if (s.data && s.processData && typeof s.data !== "string") { s.data = jQuery.param(s.data, s.traditional); } // Apply prefilters inspectPrefiltersOrTransports(prefilters, s, options, jqXHR); // If request was aborted inside a prefilter, stop there if (completed) { return jqXHR; } // We can fire global events as of now if asked to // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) fireGlobals = jQuery.event && s.global; // Watch for a new set of requests if (fireGlobals && jQuery.active++ === 0) { jQuery.event.trigger("ajaxStart"); } // Uppercase the type s.type = s.type.toUpperCase(); // Determine if request has content s.hasContent = !rnoContent.test(s.type); // Save the URL in case we're toying with the If-Modified-Since // and/or If-None-Match header later on // Remove hash to simplify url manipulation cacheURL = s.url.replace(rhash, ""); // More options handling for requests with no content if (!s.hasContent) { // Remember the hash so we can put it back uncached = s.url.slice(cacheURL.length); // If data is available and should be processed, append data to url if (s.data && (s.processData || typeof s.data === "string")) { cacheURL += (rquery.test(cacheURL) ? "&" : "?") + s.data; // #9682: remove data so that it's not used in an eventual retry delete s.data; } // Add or update anti-cache param if needed if (s.cache === false) { cacheURL = cacheURL.replace(rantiCache, "$1"); uncached = (rquery.test(cacheURL) ? "&" : "?") + "_=" + nonce++ + uncached; } // Put hash and anti-cache on the URL that will be requested (gh-1732) s.url = cacheURL + uncached; // Change '%20' to '+' if this is encoded form body content (gh-2658) } else if (s.data && s.processData && (s.contentType || "").indexOf("application/x-www-form-urlencoded") === 0) { s.data = s.data.replace(r20, "+"); } // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if (s.ifModified) { if (jQuery.lastModified[cacheURL]) { jqXHR.setRequestHeader("If-Modified-Since", jQuery.lastModified[cacheURL]); } if (jQuery.etag[cacheURL]) { jqXHR.setRequestHeader("If-None-Match", jQuery.etag[cacheURL]); } } // Set the correct header, if data is being sent if (s.data && s.hasContent && s.contentType !== false || options.contentType) { jqXHR.setRequestHeader("Content-Type", s.contentType); } // Set the Accepts header for the server, depending on the dataType jqXHR.setRequestHeader("Accept", s.dataTypes[0] && s.accepts[s.dataTypes[0]] ? s.accepts[s.dataTypes[0]] + (s.dataTypes[0] !== "*" ? ", " + allTypes + "; q=0.01" : "") : s.accepts["*"]); // Check for headers option for (i in s.headers) { jqXHR.setRequestHeader(i, s.headers[i]); } // Allow custom headers/mimetypes and early abort if (s.beforeSend && (s.beforeSend.call(callbackContext, jqXHR, s) === false || completed)) { // Abort if not done already and return return jqXHR.abort(); } // Aborting is no longer a cancellation strAbort = "abort"; // Install callbacks on deferreds completeDeferred.add(s.complete); jqXHR.done(s.success); jqXHR.fail(s.error); // Get transport transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR); // If no transport, we auto-abort if (!transport) { done(-1, "No Transport"); } else { jqXHR.readyState = 1; // Send global event if (fireGlobals) { globalEventContext.trigger("ajaxSend", [jqXHR, s]); } // If request was aborted inside ajaxSend, stop there if (completed) { return jqXHR; } // Timeout if (s.async && s.timeout > 0) { timeoutTimer = window.setTimeout(function () { jqXHR.abort("timeout"); }, s.timeout); } try { completed = false; transport.send(requestHeaders, done); } catch (e) { // Rethrow post-completion exceptions if (completed) { throw e; } // Propagate others as results done(-1, e); } } // Callback for when everything is done function done(status, nativeStatusText, responses, headers) { var isSuccess, success, error, response, modified, statusText = nativeStatusText; // Ignore repeat invocations if (completed) { return; } completed = true; // Clear timeout if it exists if (timeoutTimer) { window.clearTimeout(timeoutTimer); } // Dereference transport for early garbage collection // (no matter how long the jqXHR object will be used) transport = undefined; // Cache response headers responseHeadersString = headers || ""; // Set readyState jqXHR.readyState = status > 0 ? 4 : 0; // Determine if successful isSuccess = status >= 200 && status < 300 || status === 304; // Get response data if (responses) { response = ajaxHandleResponses(s, jqXHR, responses); } // Convert no matter what (that way responseXXX fields are always set) response = ajaxConvert(s, response, jqXHR, isSuccess); // If successful, handle type chaining if (isSuccess) { // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if (s.ifModified) { modified = jqXHR.getResponseHeader("Last-Modified"); if (modified) { jQuery.lastModified[cacheURL] = modified; } modified = jqXHR.getResponseHeader("etag"); if (modified) { jQuery.etag[cacheURL] = modified; } } // if no content if (status === 204 || s.type === "HEAD") { statusText = "nocontent"; // if not modified } else if (status === 304) { statusText = "notmodified"; // If we have data, let's convert it } else { statusText = response.state; success = response.data; error = response.error; isSuccess = !error; } } else { // Extract error from statusText and normalize for non-aborts error = statusText; if (status || !statusText) { statusText = "error"; if (status < 0) { status = 0; } } } // Set data for the fake xhr object jqXHR.status = status; jqXHR.statusText = (nativeStatusText || statusText) + ""; // Success/Error if (isSuccess) { deferred.resolveWith(callbackContext, [success, statusText, jqXHR]); } else { deferred.rejectWith(callbackContext, [jqXHR, statusText, error]); } // Status-dependent callbacks jqXHR.statusCode(_statusCode); _statusCode = undefined; if (fireGlobals) { globalEventContext.trigger(isSuccess ? "ajaxSuccess" : "ajaxError", [jqXHR, s, isSuccess ? success : error]); } // Complete completeDeferred.fireWith(callbackContext, [jqXHR, statusText]); if (fireGlobals) { globalEventContext.trigger("ajaxComplete", [jqXHR, s]); // Handle the global AJAX counter if (! --jQuery.active) { jQuery.event.trigger("ajaxStop"); } } } return jqXHR; }, getJSON: function getJSON(url, data, callback) { return jQuery.get(url, data, callback, "json"); }, getScript: function getScript(url, callback) { return jQuery.get(url, undefined, callback, "script"); } }); jQuery.each(["get", "post"], function (i, method) { jQuery[method] = function (url, data, callback, type) { // Shift arguments if data argument was omitted if (isFunction(data)) { type = type || callback; callback = data; data = undefined; } // The url can be an options object (which then must have .url) return jQuery.ajax(jQuery.extend({ url: url, type: method, dataType: type, data: data, success: callback }, jQuery.isPlainObject(url) && url)); }; }); jQuery._evalUrl = function (url) { return jQuery.ajax({ url: url, // Make this explicit, since user can override this through ajaxSetup (#11264) type: "GET", dataType: "script", cache: true, async: false, global: false, "throws": true }); }; jQuery.fn.extend({ wrapAll: function wrapAll(html) { var wrap; if (this[0]) { if (isFunction(html)) { html = html.call(this[0]); } // The elements to wrap the target around wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true); if (this[0].parentNode) { wrap.insertBefore(this[0]); } wrap.map(function () { var elem = this; while (elem.firstElementChild) { elem = elem.firstElementChild; } return elem; }).append(this); } return this; }, wrapInner: function wrapInner(html) { if (isFunction(html)) { return this.each(function (i) { jQuery(this).wrapInner(html.call(this, i)); }); } return this.each(function () { var self = jQuery(this), contents = self.contents(); if (contents.length) { contents.wrapAll(html); } else { self.append(html); } }); }, wrap: function wrap(html) { var htmlIsFunction = isFunction(html); return this.each(function (i) { jQuery(this).wrapAll(htmlIsFunction ? html.call(this, i) : html); }); }, unwrap: function unwrap(selector) { this.parent(selector).not("body").each(function () { jQuery(this).replaceWith(this.childNodes); }); return this; } }); jQuery.expr.pseudos.hidden = function (elem) { return !jQuery.expr.pseudos.visible(elem); }; jQuery.expr.pseudos.visible = function (elem) { return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length); }; jQuery.ajaxSettings.xhr = function () { try { return new window.XMLHttpRequest(); } catch (e) {} }; var xhrSuccessStatus = { // File protocol always yields status code 0, assume 200 0: 200, // Support: IE <=9 only // #1450: sometimes IE returns 1223 when it should be 204 1223: 204 }, xhrSupported = jQuery.ajaxSettings.xhr(); support.cors = !!xhrSupported && "withCredentials" in xhrSupported; support.ajax = xhrSupported = !!xhrSupported; jQuery.ajaxTransport(function (options) { var _callback, errorCallback; // Cross domain only allowed if supported through XMLHttpRequest if (support.cors || xhrSupported && !options.crossDomain) { return { send: function send(headers, complete) { var i, xhr = options.xhr(); xhr.open(options.type, options.url, options.async, options.username, options.password); // Apply custom fields if provided if (options.xhrFields) { for (i in options.xhrFields) { xhr[i] = options.xhrFields[i]; } } // Override mime type if needed if (options.mimeType && xhr.overrideMimeType) { xhr.overrideMimeType(options.mimeType); } // X-Requested-With header // For cross-domain requests, seeing as conditions for a preflight are // akin to a jigsaw puzzle, we simply never set it to be sure. // (it can always be set on a per-request basis or even using ajaxSetup) // For same-domain requests, won't change header if already provided. if (!options.crossDomain && !headers["X-Requested-With"]) { headers["X-Requested-With"] = "XMLHttpRequest"; } // Set headers for (i in headers) { xhr.setRequestHeader(i, headers[i]); } // Callback _callback = function callback(type) { return function () { if (_callback) { _callback = errorCallback = xhr.onload = xhr.onerror = xhr.onabort = xhr.ontimeout = xhr.onreadystatechange = null; if (type === "abort") { xhr.abort(); } else if (type === "error") { // Support: IE <=9 only // On a manual native abort, IE9 throws // errors on any property access that is not readyState if (typeof xhr.status !== "number") { complete(0, "error"); } else { complete( // File: protocol always yields status 0; see #8605, #14207 xhr.status, xhr.statusText); } } else { complete(xhrSuccessStatus[xhr.status] || xhr.status, xhr.statusText, // Support: IE <=9 only // IE9 has no XHR2 but throws on binary (trac-11426) // For XHR2 non-text, let the caller handle it (gh-2498) (xhr.responseType || "text") !== "text" || typeof xhr.responseText !== "string" ? { binary: xhr.response } : { text: xhr.responseText }, xhr.getAllResponseHeaders()); } } }; }; // Listen to events xhr.onload = _callback(); errorCallback = xhr.onerror = xhr.ontimeout = _callback("error"); // Support: IE 9 only // Use onreadystatechange to replace onabort // to handle uncaught aborts if (xhr.onabort !== undefined) { xhr.onabort = errorCallback; } else { xhr.onreadystatechange = function () { // Check readyState before timeout as it changes if (xhr.readyState === 4) { // Allow onerror to be called first, // but that will not handle a native abort // Also, save errorCallback to a variable // as xhr.onerror cannot be accessed window.setTimeout(function () { if (_callback) { errorCallback(); } }); } }; } // Create the abort callback _callback = _callback("abort"); try { // Do send the request (this may raise an exception) xhr.send(options.hasContent && options.data || null); } catch (e) { // #14683: Only rethrow if this hasn't been notified as an error yet if (_callback) { throw e; } } }, abort: function abort() { if (_callback) { _callback(); } } }; } }); // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) jQuery.ajaxPrefilter(function (s) { if (s.crossDomain) { s.contents.script = false; } }); // Install script dataType jQuery.ajaxSetup({ accepts: { script: "text/javascript, application/javascript, " + "application/ecmascript, application/x-ecmascript" }, contents: { script: /\b(?:java|ecma)script\b/ }, converters: { "text script": function textScript(text) { jQuery.globalEval(text); return text; } } }); // Handle cache's special case and crossDomain jQuery.ajaxPrefilter("script", function (s) { if (s.cache === undefined) { s.cache = false; } if (s.crossDomain) { s.type = "GET"; } }); // Bind script tag hack transport jQuery.ajaxTransport("script", function (s) { // This transport only deals with cross domain requests if (s.crossDomain) { var script, _callback2; return { send: function send(_, complete) { script = jQuery("