UNPKG

feeles-ide

Version:

The hackable and serializable IDE to make learning material

1,318 lines (1,064 loc) 223 kB
/*! * matter-tools 0.9.1 by Liam Brummitt 2017-01-26 * https://github.com/liabru/matter-tools * License MIT */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("Matter"), require("MatterTools"), require("jQuery")); else if(typeof define === 'function' && define.amd) define(["Matter", "MatterTools", "jQuery"], factory); else if(typeof exports === 'object') exports["Inspector"] = factory(require("Matter"), require("MatterTools"), require("jQuery")); else root["MatterTools"] = root["MatterTools"] || {}, root["MatterTools"]["Inspector"] = factory(root["Matter"], root["MatterTools"], root["jQuery"]); })(this, function(__WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_7__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = "/demo/lib"; /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ function(module, exports, __webpack_require__) { "use strict"; /** * A tool for inspecting worlds. * @module Inspector */ var Inspector = module.exports = {}; var $ = __webpack_require__(7); __webpack_require__(8); var ToolsCommon = __webpack_require__(3); var Serializer = __webpack_require__(2).Serializer; var km = __webpack_require__(9); var Matter = __webpack_require__(1); var Body = Matter.Body; var Bounds = Matter.Bounds; var Composite = Matter.Composite; var Common = Matter.Common; var Events = Matter.Events; var Mouse = Matter.Mouse; var Query = Matter.Query; var Vertices = Matter.Vertices; var Vector = Matter.Vector; var MouseConstraint = Matter.MouseConstraint; var $body; /** * Creates an inspector * @function Gui.create * @param {engine} engine * @param {render} [render] * @param {object} options * @return {inspector} The created inspector instance. */ Inspector.create = function (engine, render, options) { if (!$) { console.log('Could not create inspector, missing jQuery.'); return; } var inspector = { engine: null, render: null, isPaused: false, selected: [], selectStart: null, selectEnd: null, selectBounds: Bounds.create(), mousePrevPosition: { x: 0, y: 0 }, offset: { x: 0, y: 0 }, autoHide: true, autoRewind: true, bodyClass: '', exportIndent: 0, clipboard: [], controls: { container: null, worldTree: null }, root: Composite.create({ label: 'Root' }), keyBindings: [] }; inspector = Common.extend(inspector, options); Inspector.instance = inspector; inspector.engine = engine; inspector.render = render; if (inspector.render) { inspector.mouse = Mouse.create(inspector.render.canvas); inspector.mouseConstraint = MouseConstraint.create(engine, { mouse: inspector.mouse }); } else { inspector.mouse = { position: { x: 0, y: 0 } }; } if (Serializer) { inspector.serializer = Serializer.create(); localStorage.removeItem('pauseState'); } $body = $('body'); Composite.add(inspector.root, engine.world); engine.world.isModified = true; engine.world.parent = null; var styles = __webpack_require__(10); ToolsCommon.injectStyles(styles, 'js-tree-style'); styles = __webpack_require__(11); ToolsCommon.injectStyles(styles, 'matter-inspector-style'); inspector.keyBind = Common.chain(km, function (key) { inspector.keyBindings.push(key); }); _initControls(inspector); _initEngineEvents(inspector); _initTree(inspector); _initKeybinds(inspector); return inspector; }; /** * Destroys the inspector * @function Gui.destroy * @param {Inspector} inspector */ Inspector.destroy = function (inspector) { inspector.controls.worldTree.data('jstree').destroy(); var inspectorElements = [].slice.call(document.body.querySelectorAll('.ins-container', '.vakata-context', '.jstree-marker')); inspectorElements.forEach(ToolsCommon.domRemove); inspector.keyBindings.forEach(function (key) { km.unbind(key); }); Events.off(inspector.engine, 'beforeUpdate', inspector.beforeEngineUpdate); if (inspector.render) { Events.off(inspector.render, 'afterRender', inspector.afterRender); Events.off(inspector.mouseConstraint); } }; var _initControls = function _initControls(inspector) { var controls = inspector.controls; var $inspectorContainer = $('<div class="ins-container">'), $buttonGroup = $('<div class="ins-control-group">'), $searchBox = $('<input class="ins-search-box" type="search" placeholder="search">'), $importButton = $('<button class="ins-import-button ins-button">Import</button>'), $exportButton = $('<button class="ins-export-button ins-button">Export</button>'), $pauseButton = $('<button class="ins-pause-button ins-button">Pause</button>'), $helpButton = $('<button class="ins-help-button ins-button">Help</button>'), $addCompositeButton = $('<button class="ins-add-button ins-button">+</button>'); if (Serializer) { $buttonGroup.append($pauseButton, $importButton, $exportButton, $helpButton); } else { $buttonGroup.append($pauseButton, $helpButton); } $inspectorContainer.prepend($searchBox, $addCompositeButton); $body.prepend($inspectorContainer); controls.pauseButton = $pauseButton; controls.importButton = $importButton; controls.exportButton = $exportButton; controls.helpButton = $helpButton; controls.searchBox = $searchBox; controls.container = $inspectorContainer; controls.addCompositeButton = $addCompositeButton; controls.pauseButton.click(function () { _setPaused(inspector, !inspector.isPaused); }); controls.exportButton.click(function () { _exportFile(inspector); }); controls.importButton.click(function () { _importFile(inspector); }); controls.helpButton.click(function () { _showHelp(inspector); }); controls.addCompositeButton.click(function () { _addNewComposite(inspector); }); var searchTimeout; controls.searchBox.keyup(function () { clearTimeout(searchTimeout); searchTimeout = setTimeout(function () { var value = controls.searchBox.val(), worldTree = controls.worldTree.data('jstree'); worldTree.search(value); }, 250); }); }; var _showHelp = function _showHelp() { var help = "Matter Tools\n\n"; help += "Drag nodes in the tree to move them between composites.\n"; help += "Use browser's developer console to inspect selected objects.\n"; help += "Note: selections only render if renderer supports it.\n\n"; help += "[shift + space] pause or play simulation.\n"; help += "[right click] and drag on empty space to select a region.\n"; help += "[right click] and drag on an object to move it.\n"; help += "[right click + shift] and drag to move whole selection.\n\n"; help += "[ctrl-c] to copy selected world objects.\n"; help += "[ctrl-v] to paste copied world objects to mouse position.\n"; help += "[del] or [backspace] delete selected objects.\n\n"; help += "[shift + s] scale-xy selected objects with mouse or arrows.\n"; help += "[shift + s + d] scale-x selected objects with mouse or arrows.\n"; help += "[shift + s + f] scale-y selected objects with mouse or arrows.\n"; help += "[shift + r] rotate selected objects with mouse or arrows.\n\n"; help += "[shift + q] set selected objects as static (can't be undone).\n"; help += "[shift + i] import objects.\n"; help += "[shift + o] export selected objects.\n"; help += "[shift + h] toggle Matter.Gui.\n"; help += "[shift + y] toggle auto-hide.\n"; help += "[shift + r] toggle auto-rewind on play/pause.\n\n"; help += "[shift + j] show this help message."; alert(help); }; var _initKeybinds = function _initKeybinds(inspector) { inspector.keyBind('shift+space', function () { _setPaused(inspector, !inspector.isPaused); }); if (inspector.serializer) { inspector.keyBind('shift+o', function () { _exportFile(inspector); }); inspector.keyBind('shift+i', function () { _importFile(inspector); }); } inspector.keyBind('shift+j', function () { _showHelp(inspector); }); inspector.keyBind('shift+y', function () { inspector.autoHide = !inspector.autoHide; $body.toggleClass('ins-auto-hide gui-auto-hide', inspector.autoHide); }); inspector.keyBind('shift+r', function () { inspector.autoRewind = !inspector.autoRewind; if (!inspector.autoRewind) localStorage.removeItem('pauseState'); }); inspector.keyBind('shift+q', function () { for (var i = 0; i < inspector.selected.length; i++) { var object = inspector.selected[i].data; if (object.type === 'body' && !object.isStatic) Body.setStatic(object, true); } }); inspector.keyBind('del', function () { _deleteSelectedObjects(inspector); }); inspector.keyBind('backspace', function () { _deleteSelectedObjects(inspector); }); if (inspector.serializer) { inspector.keyBind('ctrl+c', function () { _copySelectedObjects(inspector); }); inspector.keyBind('ctrl+v', function () { _pasteSelectedObjects(inspector); }); } // prevent the backspace key from navigating back // http://stackoverflow.com/questions/1495219/how-can-i-prevent-the-backspace-key-from-navigating-back $(document).unbind('keydown').bind('keydown', function (event) { var doPrevent = false; if (event.keyCode === 8) { var d = event.srcElement || event.target; if (d.tagName.toUpperCase() === 'INPUT' && (d.type.toUpperCase() === 'TEXT' || d.type.toUpperCase() === 'PASSWORD' || d.type.toUpperCase() === 'FILE' || d.type.toUpperCase() === 'EMAIL' || d.type.toUpperCase() === 'SEARCH') || d.tagName.toUpperCase() === 'TEXTAREA') { doPrevent = d.readOnly || d.disabled; } else { doPrevent = true; } } if (doPrevent) { event.preventDefault(); } }); }; var _initTree = function _initTree(inspector) { var engine = inspector.engine, controls = inspector.controls, deferTimeout; var worldTreeOptions = { 'core': { 'check_callback': true }, 'dnd': { 'copy': false }, 'search': { 'show_only_matches': true, 'fuzzy': false }, 'types': { '#': { 'valid_children': [] }, 'body': { 'valid_children': [] }, 'constraint': { 'valid_children': [] }, 'composite': { 'valid_children': [] }, 'bodies': { 'valid_children': ['body'] }, 'constraints': { 'valid_children': ['constraint'] }, 'composites': { 'valid_children': ['composite'] } }, 'plugins': ['dnd', 'types', 'unique', 'search'] }; controls.worldTree = $('<div class="ins-world-tree">').jstree(worldTreeOptions); controls.container.append(controls.worldTree); controls.worldTree.on('changed.jstree', function (event, data) { var selected = [], worldTree = controls.worldTree.data('jstree'); if (data.action !== 'select_node') return; // defer selection update until selection has finished propagating clearTimeout(deferTimeout); deferTimeout = setTimeout(function () { data.selected = worldTree.get_selected(); for (var i = 0; i < data.selected.length; i++) { var nodeId = data.selected[i], objectType = nodeId.split('_')[0], objectId = nodeId.split('_')[1], worldObject = Composite.get(engine.world, objectId, objectType); switch (objectType) { case 'body': case 'constraint': case 'composite': selected.push(worldObject); break; } } _setSelectedObjects(inspector, selected); }, 1); }); $(document).on('dnd_stop.vakata', function (event, data) { var worldTree = controls.worldTree.data('jstree'), nodes = data.data.nodes; // handle drag and drop // move items between composites for (var i = 0; i < nodes.length; i++) { var node = worldTree.get_node(nodes[i]), parentNode = worldTree.get_node(worldTree.get_parent(nodes[i])), prevCompositeId = node.data.compositeId, newCompositeId = parentNode.data.compositeId; if (prevCompositeId === newCompositeId) continue; var nodeId = nodes[i], objectType = nodeId.split('_')[0], objectId = nodeId.split('_')[1], worldObject = Composite.get(inspector.root, objectId, objectType), prevComposite = Composite.get(inspector.root, prevCompositeId, 'composite'), newComposite = Composite.get(inspector.root, newCompositeId, 'composite'); Composite.move(prevComposite, worldObject, newComposite); } }); controls.worldTree.on('dblclick.jstree', function () { var worldTree = controls.worldTree.data('jstree'), selected = worldTree.get_selected(); // select all children of double clicked node for (var i = 0; i < selected.length; i++) { var nodeId = selected[i], objectType = nodeId.split('_')[0]; switch (objectType) { case 'composite': case 'composites': case 'bodies': case 'constraints': var children = worldTree.get_node(nodeId).children; for (var j = 0; j < children.length; j++) { worldTree.select_node(children[j], false); }break; } } }); }; var _addBodyClass = function _addBodyClass(inspector, classNames) { // only apply changes to prevent DOM lag if (inspector.bodyClass.indexOf(' ' + classNames) === -1) { $body.addClass(classNames); inspector.bodyClass = ' ' + $body.attr('class'); } }; var _removeBodyClass = function _removeBodyClass(inspector, classNames) { // only apply changes to prevent DOM lag var updateRequired = false, classes = classNames.split(' '); for (var i = 0; i < classes.length; i++) { updateRequired = inspector.bodyClass.indexOf(' ' + classes[i]) !== -1; if (updateRequired) break; } if (updateRequired) { $body.removeClass(classNames); inspector.bodyClass = ' ' + $body.attr('class'); } }; var _getMousePosition = function _getMousePosition(inspector) { return Vector.add(inspector.mouse.position, inspector.offset); }; var _initEngineEvents = function _initEngineEvents(inspector) { var engine = inspector.engine, mouse = inspector.mouse, mousePosition = _getMousePosition(inspector), controls = inspector.controls; inspector.beforeEngineUpdate = function () { // update mouse position reference mousePosition = _getMousePosition(inspector); var mouseDelta = mousePosition.x - inspector.mousePrevPosition.x, keyDelta = km.isPressed('up') + km.isPressed('right') - km.isPressed('down') - km.isPressed('left'), delta = mouseDelta + keyDelta; // update interface when world changes if (engine.world.isModified) { var data = _generateCompositeTreeNode(inspector.root, null, true); _updateTree(controls.worldTree.data('jstree'), data); _setSelectedObjects(inspector, []); } // update region selection if (inspector.selectStart !== null) { inspector.selectEnd.x = mousePosition.x; inspector.selectEnd.y = mousePosition.y; Bounds.update(inspector.selectBounds, [inspector.selectStart, inspector.selectEnd]); } // rotate mode if (km.shift && km.isPressed('r')) { var rotateSpeed = 0.03, angle = Math.max(-2, Math.min(2, delta)) * rotateSpeed; _addBodyClass(inspector, 'ins-cursor-rotate'); _rotateSelectedObjects(inspector, angle); } else { _removeBodyClass(inspector, 'ins-cursor-rotate'); } // scale mode if (km.shift && km.isPressed('s')) { var scaleSpeed = 0.02, scale = 1 + Math.max(-2, Math.min(2, delta)) * scaleSpeed; _addBodyClass(inspector, 'ins-cursor-scale'); var scaleX, scaleY; if (km.isPressed('d')) { scaleX = scale; scaleY = 1; } else if (km.isPressed('f')) { scaleX = 1; scaleY = scale; } else { scaleX = scaleY = scale; } _scaleSelectedObjects(inspector, scaleX, scaleY); } else { _removeBodyClass(inspector, 'ins-cursor-scale'); } // translate mode if (mouse.button === 2) { _addBodyClass(inspector, 'ins-cursor-move'); _moveSelectedObjects(inspector, mousePosition.x, mousePosition.y); } else { _removeBodyClass(inspector, 'ins-cursor-move'); } inspector.mousePrevPosition = Common.clone(mousePosition); }; Events.on(inspector.engine, 'beforeUpdate', inspector.beforeEngineUpdate); if (inspector.mouseConstraint) { Events.on(inspector.mouseConstraint, 'mouseup', function () { // select objects in region if making a region selection if (inspector.selectStart !== null) { var selected = Query.region(Composite.allBodies(engine.world), inspector.selectBounds); _setSelectedObjects(inspector, selected); } // clear selection region inspector.selectStart = null; inspector.selectEnd = null; Events.trigger(inspector, 'selectEnd'); }); Events.on(inspector.mouseConstraint, 'mousedown', function () { var bodies = Composite.allBodies(engine.world), constraints = Composite.allConstraints(engine.world), isUnionSelect = km.shift || km.control, worldTree = inspector.controls.worldTree.data('jstree'), i; if (mouse.button === 2) { var hasSelected = false; for (i = 0; i < bodies.length; i++) { var body = bodies[i]; if (Bounds.contains(body.bounds, mousePosition) && Vertices.contains(body.vertices, mousePosition)) { if (isUnionSelect) { _addSelectedObject(inspector, body); } else { _setSelectedObjects(inspector, [body]); } hasSelected = true; break; } } if (!hasSelected) { for (i = 0; i < constraints.length; i++) { var constraint = constraints[i], bodyA = constraint.bodyA, bodyB = constraint.bodyB; if (constraint.label.indexOf('Mouse Constraint') !== -1) continue; var pointAWorld = constraint.pointA, pointBWorld = constraint.pointB; if (bodyA) pointAWorld = Vector.add(bodyA.position, constraint.pointA); if (bodyB) pointBWorld = Vector.add(bodyB.position, constraint.pointB); if (!pointAWorld || !pointBWorld) continue; var distA = Vector.magnitudeSquared(Vector.sub(mousePosition, pointAWorld)), distB = Vector.magnitudeSquared(Vector.sub(mousePosition, pointBWorld)); if (distA < 100 || distB < 100) { if (isUnionSelect) { _addSelectedObject(inspector, constraint); } else { _setSelectedObjects(inspector, [constraint]); } hasSelected = true; break; } } if (!hasSelected) { worldTree.deselect_all(true); _setSelectedObjects(inspector, []); inspector.selectStart = Common.clone(mousePosition); inspector.selectEnd = Common.clone(mousePosition); Bounds.update(inspector.selectBounds, [inspector.selectStart, inspector.selectEnd]); Events.trigger(inspector, 'selectStart'); } else { inspector.selectStart = null; inspector.selectEnd = null; } } } if (mouse.button === 2 && inspector.selected.length > 0) { _addBodyClass(inspector, 'ins-cursor-move'); _updateSelectedMouseDownOffset(inspector); } }); } if (inspector.render) { inspector.afterRender = function () { var renderController = inspector.render.controller, context = inspector.render.context; if (renderController.inspector) renderController.inspector(inspector, context); }; Events.on(inspector.render, 'afterRender', inspector.afterRender); } }; var _deleteSelectedObjects = function _deleteSelectedObjects(inspector) { var objects = [], object, worldTree = inspector.controls.worldTree.data('jstree'), i; // delete objects in world for (i = 0; i < inspector.selected.length; i++) { object = inspector.selected[i].data; if (object !== inspector.engine.world) objects.push(object); } // also delete non-world composites (selected only in the UI tree) var selectedNodes = worldTree.get_selected(); for (i = 0; i < selectedNodes.length; i++) { var node = worldTree.get_node(selectedNodes[i]); if (node.type === 'composite') { node = worldTree.get_node(node.children[0]); if (node.data) { var compositeId = node.data.compositeId; object = Composite.get(inspector.root, compositeId, 'composite'); if (object && object !== inspector.engine.world) { objects.push(object); worldTree.delete_node(selectedNodes[i]); } } } } Composite.remove(inspector.root, objects, true); _setSelectedObjects(inspector, []); }; var _copySelectedObjects = function _copySelectedObjects(inspector) { inspector.clipboard.length = 0; // put selected objects into clipboard for (var i = 0; i < inspector.selected.length; i++) { var object = inspector.selected[i].data; if (object.type !== 'body') continue; inspector.clipboard.push(object); } }; var _pasteSelectedObjects = function _pasteSelectedObjects(inspector) { if (!inspector.serializer) { return; } var objects = [], worldTree = inspector.controls.worldTree.data('jstree'); // copy objects in world for (var i = 0; i < inspector.clipboard.length; i++) { var object = inspector.clipboard[i], clone = Serializer.clone(inspector.serializer, object); Body.translate(clone, { x: 50, y: 50 }); // add the clone to the same composite as original var node = worldTree.get_node(object.type + '_' + object.id, false), compositeId = node.data.compositeId, composite = Composite.get(inspector.engine.world, compositeId, 'composite'); Composite.add(composite, clone); objects.push(clone); } // select clones after waiting for tree to update setTimeout(function () { _setSelectedObjects(inspector, objects); }, 200); }; var _updateSelectedMouseDownOffset = function _updateSelectedMouseDownOffset(inspector) { var selected = inspector.selected, mousePosition = _getMousePosition(inspector), item, data; for (var i = 0; i < selected.length; i++) { item = selected[i]; data = item.data; if (data.position) { item.mousedownOffset = { x: mousePosition.x - data.position.x, y: mousePosition.y - data.position.y }; } else if (data.pointA && !data.bodyA) { item.mousedownOffset = { x: mousePosition.x - data.pointA.x, y: mousePosition.y - data.pointA.y }; } else if (data.pointB && !data.bodyB) { item.mousedownOffset = { x: mousePosition.x - data.pointB.x, y: mousePosition.y - data.pointB.y }; } } }; var _moveSelectedObjects = function _moveSelectedObjects(inspector, x, y) { var selected = inspector.selected, item, data; for (var i = 0; i < selected.length; i++) { item = selected[i]; data = item.data; if (!item.mousedownOffset) continue; switch (data.type) { case 'body': var delta = { x: x - data.position.x - item.mousedownOffset.x, y: y - data.position.y - item.mousedownOffset.y }; Body.translate(data, delta); data.positionPrev.x = data.position.x; data.positionPrev.y = data.position.y; break; case 'constraint': var point = data.pointA; if (data.bodyA) point = data.pointB; point.x = x - item.mousedownOffset.x; point.y = y - item.mousedownOffset.y; var initialPointA = data.bodyA ? Vector.add(data.bodyA.position, data.pointA) : data.pointA, initialPointB = data.bodyB ? Vector.add(data.bodyB.position, data.pointB) : data.pointB; data.length = Vector.magnitude(Vector.sub(initialPointA, initialPointB)); break; } } }; var _scaleSelectedObjects = function _scaleSelectedObjects(inspector, scaleX, scaleY) { var selected = inspector.selected, item, data; for (var i = 0; i < selected.length; i++) { item = selected[i]; data = item.data; switch (data.type) { case 'body': Body.scale(data, scaleX, scaleY, data.position); if (data.circleRadius) data.circleRadius *= scaleX; break; } } }; var _rotateSelectedObjects = function _rotateSelectedObjects(inspector, angle) { var selected = inspector.selected, item, data; for (var i = 0; i < selected.length; i++) { item = selected[i]; data = item.data; switch (data.type) { case 'body': Body.rotate(data, angle); break; } } }; var _setPaused = function _setPaused(inspector, isPaused) { if (isPaused) { if (inspector.autoRewind && inspector.serializer) { _setSelectedObjects(inspector, []); Serializer.loadState(inspector.serializer, inspector.engine, 'pauseState'); } inspector.engine.timing.timeScale = 0; inspector.isPaused = true; inspector.controls.pauseButton.text('Play'); Events.trigger(inspector, 'paused'); } else { if (inspector.autoRewind && inspector.serializer) { Serializer.saveState(inspector.serializer, inspector.engine, 'pauseState'); } inspector.engine.timing.timeScale = 1; inspector.isPaused = false; inspector.controls.pauseButton.text('Pause'); Events.trigger(inspector, 'play'); } }; var _setSelectedObjects = function _setSelectedObjects(inspector, objects) { var worldTree = inspector.controls.worldTree.data('jstree'), data, i; for (i = 0; i < inspector.selected.length; i++) { data = inspector.selected[i].data; worldTree.deselect_node(data.type + '_' + data.id, true); } inspector.selected = []; if (objects.length > 0) { console.clear(); } for (i = 0; i < objects.length; i++) { data = objects[i]; if (data) { // add the object to the selection _addSelectedObject(inspector, data); // log selected objects to console for property inspection if (i < 5) { console.log(data.label + ' ' + data.id + ': %O', data); } else if (i === 6) { console.warn('Omitted inspecting ' + (objects.length - 5) + ' more objects'); } } } }; var _addSelectedObject = function _addSelectedObject(inspector, object) { if (!object) return; var worldTree = inspector.controls.worldTree.data('jstree'); inspector.selected.push({ data: object }); worldTree.select_node(object.type + '_' + object.id, true); }; var _updateTree = function _updateTree(tree, data) { data[0].state = data[0].state || { opened: true }; tree.settings.core.data = data; tree.refresh(-1); }; var _generateCompositeTreeNode = function _generateCompositeTreeNode(composite, compositeId, isRoot) { var children = [], node = { id: 'composite_' + composite.id, data: { compositeId: compositeId }, type: 'composite', text: (composite.label ? composite.label : 'Composite') + ' ' + composite.id, 'li_attr': { 'class': 'jstree-node-type-composite' } }; var childNode = _generateCompositesTreeNode(composite.composites, composite.id); childNode.id = 'composites_' + composite.id; children.push(childNode); if (isRoot) return childNode.children; childNode = _generateBodiesTreeNode(composite.bodies, composite.id); childNode.id = 'bodies_' + composite.id; children.push(childNode); childNode = _generateConstraintsTreeNode(composite.constraints, composite.id); childNode.id = 'constraints_' + composite.id; children.push(childNode); node.children = children; return node; }; var _generateCompositesTreeNode = function _generateCompositesTreeNode(composites, compositeId) { var node = { type: 'composites', text: 'Composites', data: { compositeId: compositeId }, children: [], 'li_attr': { 'class': 'jstree-node-type-composites' } }; for (var i = 0; i < composites.length; i++) { var composite = composites[i]; node.children.push(_generateCompositeTreeNode(composite, compositeId)); } return node; }; var _generateBodiesTreeNode = function _generateBodiesTreeNode(bodies, compositeId) { var node = { type: 'bodies', text: 'Bodies', data: { compositeId: compositeId }, children: [], 'li_attr': { 'class': 'jstree-node-type-bodies' } }; for (var i = 0; i < bodies.length; i++) { var body = bodies[i]; node.children.push({ type: 'body', id: 'body_' + body.id, data: { compositeId: compositeId }, text: (body.label ? body.label : 'Body') + ' ' + body.id, 'li_attr': { 'class': 'jstree-node-type-body' } }); } return node; }; var _generateConstraintsTreeNode = function _generateConstraintsTreeNode(constraints, compositeId) { var node = { type: 'constraints', text: 'Constraints', data: { compositeId: compositeId }, children: [], 'li_attr': { 'class': 'jstree-node-type-constraints' } }; for (var i = 0; i < constraints.length; i++) { var constraint = constraints[i]; node.children.push({ type: 'constraint', id: 'constraint_' + constraint.id, data: { compositeId: compositeId }, text: (constraint.label ? constraint.label : 'Constraint') + ' ' + constraint.id, 'li_attr': { 'class': 'jstree-node-type-constraint' } }); } return node; }; var _addNewComposite = function _addNewComposite(inspector) { var newComposite = Composite.create(); Composite.add(inspector.root, newComposite); // move new composite to the start so that it appears top of tree inspector.root.composites.splice(inspector.root.composites.length - 1, 1); inspector.root.composites.unshift(newComposite); Composite.setModified(inspector.engine.world, true, true, false); }; var _exportFile = function _exportFile(inspector) { if (!inspector.serializer) { alert('No serializer.'); return; } if (inspector.selected.length === 0) { alert('No objects were selected, so export could not be created. Can only export objects that are in the World composite.'); return; } var fileName = 'export-objects', exportComposite = Composite.create({ label: 'Exported Objects' }); // add everything else, must be in top-down order for (var i = 0; i < inspector.selected.length; i++) { var object = inspector.selected[i].data; // skip if it's already in the composite tree // this means orphans will be added in the root if (Composite.get(exportComposite, object.id, object.type)) continue; Composite.add(exportComposite, object); // better filename for small exports if (inspector.selected.length === 1) fileName = 'export-' + object.label + '-' + object.id; } // santise filename fileName = fileName.toLowerCase().replace(/[^\w\-]/g, '') + '.json'; // serialise var json = Serializer.serialise(inspector.serializer, exportComposite, inspector.exportIndent); // launch export download var _isWebkit = 'WebkitAppearance' in document.documentElement.style; if (_isWebkit) { var blob = new Blob([json], { type: 'application/json' }), anchor = document.createElement('a'); anchor.download = fileName; anchor.href = (window.webkitURL || window.URL).createObjectURL(blob); anchor.dataset.downloadurl = ['application/json', anchor.download, anchor.href].join(':'); anchor.click(); } else { window.open('data:application/json;charset=utf-8,' + escape(json)); } Events.trigger(inspector, 'export'); }; var _importFile = function _importFile(inspector) { if (!inspector.serializer) { alert('No serializer.'); return; } var element = document.createElement('div'), fileInput; element.innerHTML = '<input type="file">'; fileInput = element.firstChild; fileInput.addEventListener('change', function () { var file = fileInput.files[0]; if (file.name.match(/\.(txt|json)$/)) { var reader = new FileReader(); reader.onload = function () { var importedComposite = inspector.serializer.parse(reader.result); if (importedComposite) { importedComposite.label = 'Imported Objects'; Composite.rebase(importedComposite); Composite.add(inspector.root, importedComposite); // move imported composite to the start so that it appears top of tree inspector.root.composites.splice(inspector.root.composites.length - 1, 1); inspector.root.composites.unshift(importedComposite); var worldTree = inspector.controls.worldTree.data('jstree'), data = _generateCompositeTreeNode(inspector.root, null, true); _updateTree(worldTree, data); } }; reader.readAsText(file); } else { alert('File not supported, .json or .txt JSON files only'); } }); fileInput.click(); }; /* * * Events Documentation * */ /** * Fired after the inspector's import button pressed * * @event export * @param {} event An event object * @param {} event.source The source object of the event * @param {} event.name The name of the event */ /** * Fired after the inspector's export button pressed * * @event import * @param {} event An event object * @param {} event.source The source object of the event * @param {} event.name The name of the event */ /** * Fired after the inspector user starts making a selection * * @event selectStart * @param {} event An event object * @param {} event.source The source object of the event * @param {} event.name The name of the event */ /** * Fired after the inspector user ends making a selection * * @event selectEnd * @param {} event An event object * @param {} event.source The source object of the event * @param {} event.name The name of the event */ /** * Fired after the inspector is paused * * @event pause * @param {} event An event object * @param {} event.source The source object of the event * @param {} event.name The name of the event */ /** * Fired after the inspector is played * * @event play * @param {} event An event object * @param {} event.source The source object of the event * @param {} event.name The name of the event */ /*** EXPORTS FROM exports-loader ***/ /***/ }, /* 1 */ /***/ function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_1__; /***/ }, /* 2 */ /***/ function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_2__; /***/ }, /* 3 */ /***/ function(module, exports) { "use strict"; /** * @class Common */ var Common = module.exports = {}; Common.injectStyles = function (styles, id) { if (document.getElementById(id)) { return; } var root = document.createElement('div'); root.innerHTML = '<style id="' + id + '" type="text/css">' + styles + '</style>'; var lastStyle = document.head.querySelector('style:last-of-type'); Common.domInsertBefore(root.firstElementChild, lastStyle); }; Common.injectScript = function (url, id, callback) { if (document.getElementById(id)) { return; } var script = document.createElement('script'); script.id = id; script.src = url; script.onload = callback; document.body.appendChild(script); }; Common.domRemove = function (element) { return element.parentElement.removeChild(element); }; Common.domInsertBefore = function (element, before) { return before.parentNode.insertBefore(element, before.previousElementSibling); }; /*** EXPORTS FROM exports-loader ***/ /***/ }, /* 4 */, /* 5 */, /* 6 */, /* 7 */ /***/ function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_7__; /***/ }, /* 8 */ /***/ function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! jsTree - v3.3.3 - 2016-10-31 - (MIT) */ !function(a){"use strict"; true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(7)], __WEBPACK_AMD_DEFINE_FACTORY__ = (a), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):"undefined"!=typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a,b){"use strict";if(!a.jstree){var c=0,d=!1,e=!1,f=!1,g=[],h=a("script:last").attr("src"),i=window.document;a.jstree={version:"3.3.3",defaults:{plugins:[]},plugins:{},path:h&&-1!==h.indexOf("/")?h.replace(/\/[^\/]+$/,""):"",idregex:/[\\:&!^|()\[\]<>@*'+~#";.,=\- \/${}%?`]/g,root:"#"},a.jstree.create=function(b,d){var e=new a.jstree.core(++c),f=d;return d=a.extend(!0,{},a.jstree.defaults,d),f&&f.plugins&&(d.plugins=f.plugins),a.each(d.plugins,function(a,b){"core"!==a&&(e=e.plugin(b,d[b]))}),a(b).data("jstree",e),e.init(b,d),e},a.jstree.destroy=function(){a(".jstree:jstree").jstree("destroy"),a(i).off(".jstree")},a.jstree.core=function(a){this._id=a,this._cnt=0,this._wrk=null,this._data={core:{themes:{name:!1,dots:!1,icons:!1,ellipsis:!1},selected:[],last_error:{},working:!1,worker_queue:[],focused:null}}},a.jstree.reference=function(b){var c=null,d=null;if(!b||!b.id||b.tagName&&b.nodeType||(b=b.id),!d||!d.length)try{d=a(b)}catch(e){}if(!d||!d.length)try{d=a("#"+b.replace(a.jstree.idregex,"\\$&"))}catch(e){}return d&&d.length&&(d=d.closest(".jstree")).length&&(d=d.data("jstree"))?c=d:a(".jstree").each(function(){var d=a(this).data("jstree");return d&&d._model.data[b]?(c=d,!1):void 0}),c},a.fn.jstree=function(c){var d="string"==typeof c,e=Array.prototype.slice.call(arguments,1),f=null;return c!==!0||this.length?(this.each(function(){var g=a.jstree.reference(this),h=d&&g?g[c]:null;return f=d&&h?h.apply(g,e):null,g||d||c!==b&&!a.isPlainObject(c)||a.jstree.create(this,c),(g&&!d||c===!0)&&(f=g||!1),null!==f&&f!==b?!1:void 0}),null!==f&&f!==b?f:this):!1},a.expr.pseudos.jstree=a.expr.createPseudo(function(c){return function(c){return a(c).hasClass("jstree")&&a(c).data("jstree")!==b}}),a.jstree.defaults.core={data:!1,strings:!1,check_callback:!1,error:a.noop,animation:200,multiple:!0,themes:{name:!1,url:!1,dir:!1,dots:!0,icons:!0,ellipsis:!1,stripes:!1,variant:!1,responsive:!1},expand_selected_onload:!0,worker:!0,force_text:!1,dblclick_toggle:!0},a.jstree.core.prototype={plugin:function(b,c){var d=a.jstree.plugins[b];return d?(this._data[b]={},d.prototype=this,new d(c,this)):this},init:function(b,c){this._model={data:{},changed:[],force_full_redraw:!1,redraw_timeout:!1,default_state:{loaded:!0,opened:!1,selected:!1,disabled:!1}},this._model.data[a.jstree.root]={id:a.jstree.root,parent:null,parents:[],children:[],children_d:[],state:{loaded:!1}},this.element=a(b).addClass("jstree jstree-"+this._id),this.settings=c,this._data.core.ready=!1,this._data.core.loaded=!1,this._data.core.rtl="rtl"===this.element.css("direction"),this.element[this._data.core.rtl?"addClass":"removeClass"]("jstree-rtl"),this.element.attr("role","tree"),this.settings.core.multiple&&this.element.attr("aria-multiselectable",!0),this.element.attr("tabindex")||this.element.attr("tabindex","0"),this.bind(),this.trigger("init"),this._data.core.original_container_html=this.element.find(" > ul > li").clone(!0),this._data.core.original_container_html.find("li").addBack().contents().filter(function(){return 3===this.nodeType&&(!this.nodeValue||/^\s+$/.test(this.nodeValue))}).remove(),this.element.html("<ul class='jstree-container-ul jstree-children' role='group'><li id='j"+this._id+"_loading' class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='tree-item'><i class='jstree-icon jstree-ocl'></i><a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>"+this.get_string("Loading ...")+"</a></li></ul>"),this.element.attr("aria-activedescendant","j"+this._id+"_loading"),this._data.core.li_height=this.get_container_ul().children("li").first().height()||24,this._data.core.node=this._create_prototype_node(),this.trigger("loading"),this.load_node(a.jstree.root)},destroy:function(a){if(this._wrk)try{window.URL.revokeObjectURL(this._wrk),this._wrk=null}catch(b){}a||this.element.empty(),this.teardown()},_create_prototype_node:function(){var a=i.createElement("LI"),b,c;return a.setAttribute("role","treeitem"),b=i.createElement("I"),b.className="jstree-icon jstree-ocl",b.setAttribute("role","presentation"),a.appendChild(b),b=i.createElement("A"),b.className="jstree-anchor",b.setAttribute("href","#"),b.setAttribute("tabindex","-1"),c=i.createElement("I"),c.className="jstree-icon jstree-themeicon",c.setAttribute("role","presentation"),b.appendChild(c),a.appendChild(b),b=c=null,a},teardown:function(){this.unbind(),this.element.removeClass("jstree").removeData("jstree").find("[class^='jstree']").addBack().attr("class",function(){return this.className.replace(/jstree[^ ]*|$/gi,"")}),this.element=null},bind:function(){var b="",c=null,d=0;this.element.on("dblclick.jstree",function(a){if(a.target.tagName&&"input"===a.target.tagName.toLowerCase())return!0;if(i.selection&&i.selection.empty)i.selection.empty();else if(window.getSelection){var b=window.getSelection();try{b.removeAllRanges(),b.collapse()}catch(c){}}}).on("mousedown.jstree",a.proxy(function(a){a.target===this.element[0]&&(a.preventDefault(),d=+new Date)},this)).on("mousedown.jstree",".jstree-ocl",function(a){a.preventDefault()}).on("click.jstree",".jstree-ocl",a.proxy(function(a){this.toggle_node(a.target)},this)).on("dblclick.jstree",".jstree-anchor",a.proxy(function(a){return a.target.tagName&&"input"===a.target.tagName.toLowerCase()?!0:void(this.settings.core.dblclick_toggle&&this.toggle_node(a.target))},this)).on("click.jstree",".jstree-anchor",a.proxy(function(b){b.preventDefault(),b.currentTarget!==i.activeElement&&a(b.currentTarget).focus(),this.activate_node(b.currentTarget,b)},this)).on("keydown.jstree",".jstree-anchor",a.proxy(function(b){if(b.target.tagName&&"input"===b.target.tagName.toLowerCase())return!0;if(32!==b.which&&13!==b.which&&(b.shiftKey||b.ctrlKey||b.altKey||b.metaKey))return!0;var c=null;switch(this._data.core.rtl&&(37===b.which?b.which=39:39===b.which&&(b.which=37)),b.which){case 32:b.ctrlKey&&(b.type="click",a(b.currentTarget).trigger(b));break;case 13:b.type="click",a(b.currentTarget).trigger(b);break;case 37:b.preventDefault(),this.is_open(b.currentTarget)?this.close_node(b.currentTarget):(c=this.get_parent(b.currentTarget),c&&c.id!==a.jstree.root&&this.get_node(c,!0).children(".jstree-anchor").focus());break;case 38:b.preventDefault(),c=this.get_prev_dom(b.currentTarget),c&&c.length&&c.children(".jstree-anchor").focus();break;case 39:b.preventDefault(),this.is_closed(b.currentTarget)?this.open_node(b.currentTarget,function(a){this.get_node(a,!0).children(".jstree-anchor").focus()}):this.is_open(b.currentTarget)&&(c=this.get_node(b.currentTarget,!0).children(".jstree-children")[0],c&&a(this._firstChild(c)).children(".jstree-anchor").focus());break;case 40:b.preventDefault(),c=this.get_next_dom(b.currentTarget),c&&c.length&&c.children(".jstree-anchor").focus();break;case 106:this.open_all();break;case 36:b.preventDefault(),c=this._firstChild(this.get_container_ul()[0]),c&&a(c).children(".jstree-anchor").filter(":visible").focus();break;case 35:b.preventDefault(),this.element.find(".jstree-anchor").filter(":visible").last().focus();break;case 113:b.preventDefault(),this.edit(b.currentTarget)}},this)).on("load_node.jstree",a.proxy(function(b,c){c.status&&(c.node.id!==a.jstree.root||this._data.core.loaded||(this._data.core.loaded=!0,this._firstChild(this.get_container_ul()[0])&&this.element.attr("aria-activedescendant",this._firstChild(this.get_container_ul()[0]).id),this.trigger("loaded")),this._data.core.ready||setTimeout(a.proxy(function(){if(this.element&&!this.get_container_ul().find(".jstree-loading").length){if(this._data.core.ready=!0,this._data.core.selected.length){if(this.settings.core.expand_selected_onload){var b=[],c,d;for(c=0,d=this._data.core.selected.length;d>c;c++)b=b.concat(this._model.data[this._data.core.selected[c]].parents);for(b=a.vakata.array_unique(b),c=0,d=b.length;d>c;c++)this.open_node(b[c],!1,0)}this.trigger("changed",{action:"ready",selected:this._data.core.selected})}this.trigger("ready")}},this),0))},this)).on("keypress.jstree",a.proxy(function(d){if(d.target.tagName&&"input"===d.target.tagName.toLowerCase())return!0;c&&clearTimeout(c),c=setTimeout(function(){b=""},500);var e=String.fromCharCode(d.which).toLowerCase(),f=this.element.find(".jstree-anchor").filter(":visible"),g=f.index(i.activeElement)||0,h=!1;if(b+=e,b.length>1){if(f.slice(g).each(a.proxy(function(c,d){return 0===a(d).text().toLowerCase().indexOf(b)?(a(d).focus(),h=!0,!1):void 0},this)),h)return;if(f.slice(0,g).each(a.proxy(function(c,d){return 0===a(d).text().toLowerCase().indexOf(b)?(a(d).focus(),h=!0,!1):void 0},this)),h)return}if(new RegExp("^"+e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")+"+$").test(b)){if(f.slice(g+1).each(a.proxy(function(b,c){return a(c).text().toLowerCase().charAt(0)===e?(a(c).focus(),h=!0,!1):void 0},this)),h)return;if(f.slice(0,g+1).each(a.proxy(function(b,c){return a(c).text().toLowerCase().charAt(0)===e?(a(c).focus(),h=!0,!1):void 0},this)),h)return}},this)).on("init.jstree",a.proxy(function(){var a=this.settings.core.themes;this._data.core.themes.dots=a.dots,this._data.core.themes.stripes=a.stripes,this._data.core.themes.icons=a.icons,this._data.core.themes.ellipsis=a.ellipsis,this.set_theme(a.name||"default",a.url),this.set_theme_variant(a.variant)},this)).on("loading.jstree",a.proxy(function(){this[this._data.core.themes.dots?"show_dots":"hide_dots"](),this[this._data.core.themes.icons?"show_icons":"hide_icons"](),this[this._data.core.themes.stripes?"show_stripes":"hide_stripes"](),this[this._data.core.themes.ellipsis?"show_ellipsis":"hide_ellipsis"]()},this)).on("blur.jstree",".jstree-anchor",a.proxy(function(b){this._data.core.focused=null,a(b.currentTarget).filter(".jstree-hovered").mouseleave(),this.element.attr("tabindex","0")},this)).on("focus.jstree",".jstree-anchor",a.proxy(function(b){var c=this.get_node(b.currentTarget);c&&c.id&&(this._data.core.focused=c.id),this.element.find(".jstree-hovered").not(b.currentTarget).mouseleave(),a(b.currentTarget).mouseenter(),this.element.attr("tabindex","-1")},this)).on("focus.jstree",a.proxy(function(){if(+new Date-d>500&&!this._data.core.focused){d=0;var a=this.get_node(this.element.attr("aria-activedescendant"),!0);a&&a.find("> .jstree-anchor").focus()}},this)).on("mouseenter.jstree",".jstree-anchor",a.proxy(function(a){this.hover_node(a.currentTarget)},this)).on("mouseleave.jstree",".jstree-anchor",a.proxy(function(a){this.dehover_node(a.currentTarget)},this))},unbind:function(){this.element.off(".jstree"),a(i).off(".jstree-"+this._id)},trigger:function(a,b){b||(b={}),b.instance=this,this.element.triggerHandler(a.replace(".jstree","")+".jstree",b)},get_cont