UNPKG

whs

Version:

Super-fast 3D framework for Web Applications & Games. Based on Three.js

1,767 lines (1,468 loc) 461 kB
/* WhitestormJS Framework v2.1.9 */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('three')) : typeof define === 'function' && define.amd ? define(['exports', 'three'], factory) : (factory((global.WHS = global.WHS || {}),global.THREE)); }(this, (function (exports,three) { 'use strict'; var extend = function extend(object) { for (var _len = arguments.length, extensions = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { extensions[_key - 1] = arguments[_key]; } // $.extend alternative, ... is the spread operator. var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = extensions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var extension = _step.value; // console.log(extension); // console.log(typeof extension); if (!extension) continue; // Ignore null and undefined objects and parameters. var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = Object.getOwnPropertyNames(extension)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var prop = _step2.value; // Do not traverse the prototype chain. if (object[prop] !== undefined && extension[prop] && object[prop].toString() === '[object Object]' && extension[prop].toString() === '[object Object]') { // Goes deep only if object[prop] and extension[prop] are both objects ! if (object[prop].constructor === Object) extend(object[prop], extension[prop]); } else object[prop] = typeof object[prop] === 'undefined' ? extension[prop] : object[prop]; if (typeof object[prop] === 'undefined' && Array.isArray(extension[prop])) object[prop] = extension[prop].slice(); // Add values that do not already exist. else if (typeof object[prop] === 'undefined' && Array.isArray(extension[prop])) object[prop] = extension[prop]; } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } return object; }; var instruct = function instruct(array, instArray) { var tempObject = {}; for (var i = 0, max = instArray.length; i < max; i++) { var guide = instArray[i]; tempObject[guide] = array[i]; } return tempObject; }; var transformData = function transformData(object, instructions) { for (var key in instructions) { if (Array.isArray(object[key])) object[key] = instruct(object[key], instructions[key]);else if (object[key] instanceof Object && !Array.isArray(instructions[key])) object[key] = transformData(object[key], instructions[key]); } return object; }; var toArray = function toArray(object, instruction) { var tempArray = []; for (var i = 0, max = instruction.length; i < max; i++) { var guide = instruction[i]; tempArray[i] = object[guide]; } return tempArray; }; var minivents_commonjs = function Events(target){ var events = {}, empty = []; target = target || this; /** * On: listen to events */ target.on = function(type, func, ctx){ (events[type] = events[type] || []).push([func, ctx]); }; /** * Off: stop listening to event / specific callback */ target.off = function(type, func){ type || (events = {}); var list = events[type] || empty, i = list.length = func ? list.length : 0; while(i--) func == list[i][0] && list.splice(i,1); }; /** * Emit: send event, callbacks will be triggered */ target.emit = function(type){ var e = events[type] || empty, list = e.length > 0 ? e.slice(0, e.length) : e, i=0, j; while(j=list[i++]) j[0].apply(j[1], empty.slice.call(arguments, 1)); }; }; var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var defineProperty = function (obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; var inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }; var possibleConstructorReturn = function (self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }; var slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var CompositionError = function (_Error) { inherits(CompositionError, _Error); function CompositionError(classInstance, message, component) { classCallCheck(this, CompositionError); var _this = possibleConstructorReturn(this, (CompositionError.__proto__ || Object.getPrototypeOf(CompositionError)).call(this, '@' + classInstance + ': ' + message)); var stackArray = _this.stack.split('\n'); stackArray.splice(1, 2); _this.stack = stackArray.join('\n'); if (console) console.error('Component:', component); _this.name = 'CompositionError'; return _this; } return CompositionError; }(Error); var DependencyError = function (_Error2) { inherits(DependencyError, _Error2); function DependencyError(classInstance, message, activeModule) { var dependencyModule = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; classCallCheck(this, DependencyError); var _this2 = possibleConstructorReturn(this, (DependencyError.__proto__ || Object.getPrototypeOf(DependencyError)).call(this, '@' + classInstance + ': ' + message)); var stackArray = _this2.stack.split('\n'); stackArray.splice(1, 2); _this2.stack = stackArray.join('\n'); if (console) console.error('Active module:', activeModule); if (console && dependencyModule) console.error('Dependency published by module:', dependencyModule); _this2.name = 'DependencyError'; return _this2; } return DependencyError; }(Error); var ManagerError = function (_Error3) { inherits(ManagerError, _Error3); function ManagerError(classInstance, message, component) { var activeModule = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; classCallCheck(this, ManagerError); var _this3 = possibleConstructorReturn(this, (ManagerError.__proto__ || Object.getPrototypeOf(ManagerError)).call(this, '@' + classInstance + ': ' + message)); var stackArray = _this3.stack.split('\n'); stackArray.splice(1, 2); _this3.stack = stackArray.join('\n'); if (console) console.error('Component:', component); if (console && activeModule) console.error('Active module:', activeModule); _this3.name = 'ManagerError'; return _this3; } return ManagerError; }(Error); // Check for Three.js var warnDeps = function warnDeps() { throw new Error('WhitestormJS Framework requires Three.js r84. https://threejs.org/'); }; try { if (!three.REVISION) warnDeps(); } catch (err) { warnDeps(); } /** * @class ModuleSystem * @category core * @description Provides API for classes that will use Modules.<br/> * This class includes basic event system with those supported methods: * <pre>.on()</pre><pre>.off()</pre><pre>.emit()</pre> * @extends Events * @memberof module:core */ var ModuleSystem = function (_Events) { inherits(ModuleSystem, _Events); function ModuleSystem() { classCallCheck(this, ModuleSystem); return possibleConstructorReturn(this, (ModuleSystem.__proto__ || Object.getPrototypeOf(ModuleSystem)).apply(this, arguments)); } createClass(ModuleSystem, [{ key: 'integrateModules', // INTEGRATING /** * @method integrateModules * @instance * @description This method applies all modules from .modules collection. * @param {Object} [source] If source (should be a component) is provided, will replace .modules with source's one before executing modules. * @memberof module:core.ModuleSystem */ value: function integrateModules(source) { if (!this.modules && !source) return; if (source && source.modules) this.modules = source.modules.slice(0); if (this.modules) { for (var i = 0, max = this.modules.length; i < max; i++) { this.applyModule(this.modules[i], false); } } if (source) this.applyBridge({ onCopy: source }); } // APPLYING MODULE (...and a "bridge" for module) /** * @method applyBridge * @instance * @description Makes component-specific API to work with modules. * @param {Object} bridgeMap * @return {Object} Returns object with modified values. * @memberof module:core.ModuleSystem */ }, { key: 'applyBridge', value: function applyBridge() { var bridgeMap = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var modules = this.modules; if (!modules) return bridgeMap; for (var i = 0, max = modules.length; i < max; i++) { for (var key in bridgeMap) { if (bridgeMap[key]) { var module = modules[i]; if (module && module.bridge && module.bridge[key]) bridgeMap[key] = module.bridge[key].apply(this, [bridgeMap[key], module]); } } } return bridgeMap; } /** * @method applyCommand * @instance * @description .applyCommand runs a method called `name` on all modules. * @param {String} name the method name. * @param {Function} [cb=(func, moduleScope) => func.apply(this, [moduleScope])] How the function is wrapped/ * @memberof module:core.ModuleSystem */ }, { key: 'applyCommand', value: function applyCommand(name) { var _this2 = this; var cb = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function (func, moduleScope) { return func.apply(_this2, [moduleScope]); }; var modules = this.modules; if (!modules) return; for (var i = 0, max = modules.length; i < max; i++) { var module = modules[i]; if (name in module) cb(module[name], module); } } /** * @method applyModule * @instance * @description .applyModule is also used in .integrateModules() function. * It does exactly what its name says (applies module to component or app). * @param {Object} module the module to apply * @param {Boolean} [push=true] * @return {Object} Returns module that was applied. * @throws {ManagerError} * @memberof module:core.ModuleSystem */ }, { key: 'applyModule', value: function applyModule(module) { var push = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; if (!module) return; if (push && this.modules) this.modules.push(module);else if (push) this.modules = [module]; if (this.manager) this.manager.active(module); if (module.manager && this.manager) module.manager(this.manager);else if (module.manager) { throw new ManagerError('Component', 'Module requires ModuleManager that is turned off for this component', this, module); } if (module.integrate) module.integrate.bind(this)(module); return module; } /** * @method disposeModules * @instance * @description Disposes of all modules * @memberof module:core.ModuleSystem */ }, { key: 'disposeModules', value: function disposeModules() { while (this.modules.length) { this.disposeModule(this.modules[0]); } } /** * @method disposeModule * @instance * @description Disposes of the given module * @param {Object} module the module to dispose * @return {Module} Returns module that was removed. * @memberof module:core.ModuleSystem */ }, { key: 'disposeModule', value: function disposeModule(module) { if (!module) return; this.modules.splice(this.modules.indexOf(module), 1); if (module.dispose) module.dispose.bind(this)(module); return module; } // PIPED METHOD /** * @method module * @instance * @description piped version of .applyModule(). * @param {Object} module the module to apply * @return {this} returns this - app/component * @throws {ManagerError} * @memberof module:core.ModuleSystem * @example <caption>Piped modules</caption> * component * .module(new Module1()) * .module(new Module2()) * .module(new Module3()) */ }, { key: 'module', value: function module(_module) { this.applyModule(_module); return this; } }]); return ModuleSystem; }(minivents_commonjs); /** Detect free variable `global` from Node.js. */ var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; /** Detect free variable `self`. */ var freeSelf = typeof self == 'object' && self && self.Object === Object && self; /** Used as a reference to the global object. */ var root = freeGlobal || freeSelf || Function('return this')(); /** Built-in value references. */ var Symbol$1 = root.Symbol; /** Used for built-in method references. */ var objectProto$1 = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$1 = objectProto$1.hasOwnProperty; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var nativeObjectToString = objectProto$1.toString; /** Built-in value references. */ var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined; /** * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. * * @private * @param {*} value The value to query. * @returns {string} Returns the raw `toStringTag`. */ function getRawTag(value) { var isOwn = hasOwnProperty$1.call(value, symToStringTag$1), tag = value[symToStringTag$1]; try { value[symToStringTag$1] = undefined; var unmasked = true; } catch (e) {} var result = nativeObjectToString.call(value); if (unmasked) { if (isOwn) { value[symToStringTag$1] = tag; } else { delete value[symToStringTag$1]; } } return result; } /** Used for built-in method references. */ var objectProto$2 = Object.prototype; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var nativeObjectToString$1 = objectProto$2.toString; /** * Converts `value` to a string using `Object.prototype.toString`. * * @private * @param {*} value The value to convert. * @returns {string} Returns the converted string. */ function objectToString(value) { return nativeObjectToString$1.call(value); } /** `Object#toString` result references. */ var nullTag = '[object Null]'; var undefinedTag = '[object Undefined]'; /** Built-in value references. */ var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : undefined; /** * The base implementation of `getTag` without fallbacks for buggy environments. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ function baseGetTag(value) { if (value == null) { return value === undefined ? undefinedTag : nullTag; } return (symToStringTag && symToStringTag in Object(value)) ? getRawTag(value) : objectToString(value); } /** * Creates a unary function that invokes `func` with its argument transformed. * * @private * @param {Function} func The function to wrap. * @param {Function} transform The argument transform. * @returns {Function} Returns the new function. */ function overArg(func, transform) { return function(arg) { return func(transform(arg)); }; } /** Built-in value references. */ var getPrototype = overArg(Object.getPrototypeOf, Object); /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike(value) { return value != null && typeof value == 'object'; } /** `Object#toString` result references. */ var objectTag = '[object Object]'; /** Used for built-in method references. */ var funcProto = Function.prototype; var objectProto = Object.prototype; /** Used to resolve the decompiled source of functions. */ var funcToString = funcProto.toString; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** Used to infer the `Object` constructor. */ var objectCtorString = funcToString.call(Object); /** * Checks if `value` is a plain object, that is, an object created by the * `Object` constructor or one with a `[[Prototype]]` of `null`. * * @static * @memberOf _ * @since 0.8.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. * @example * * function Foo() { * this.a = 1; * } * * _.isPlainObject(new Foo); * // => false * * _.isPlainObject([1, 2, 3]); * // => false * * _.isPlainObject({ 'x': 0, 'y': 0 }); * // => true * * _.isPlainObject(Object.create(null)); * // => true */ function isPlainObject(value) { if (!isObjectLike(value) || baseGetTag(value) != objectTag) { return false; } var proto = getPrototype(value); if (proto === null) { return true; } var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; return typeof Ctor == 'function' && Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString; } function symbolObservablePonyfill(root) { var result; var Symbol = root.Symbol; if (typeof Symbol === 'function') { if (Symbol.observable) { result = Symbol.observable; } else { result = Symbol('observable'); Symbol.observable = result; } } else { result = '@@observable'; } return result; } /* global window */ var root$2; if (typeof self !== 'undefined') { root$2 = self; } else if (typeof window !== 'undefined') { root$2 = window; } else if (typeof global !== 'undefined') { root$2 = global; } else if (typeof module !== 'undefined') { root$2 = module; } else { root$2 = Function('return this')(); } var result = symbolObservablePonyfill(root$2); /** * These are private action types reserved by Redux. * For any unknown actions, you must return the current state. * If the current state is undefined, you must return the initial state. * Do not reference these action types directly in your code. */ var ActionTypes = { INIT: '@@redux/INIT' /** * Creates a Redux store that holds the state tree. * The only way to change the data in the store is to call `dispatch()` on it. * * There should only be a single store in your app. To specify how different * parts of the state tree respond to actions, you may combine several reducers * into a single reducer function by using `combineReducers`. * * @param {Function} reducer A function that returns the next state tree, given * the current state tree and the action to handle. * * @param {any} [preloadedState] The initial state. You may optionally specify it * to hydrate the state from the server in universal apps, or to restore a * previously serialized user session. * If you use `combineReducers` to produce the root reducer function, this must be * an object with the same shape as `combineReducers` keys. * * @param {Function} [enhancer] The store enhancer. You may optionally specify it * to enhance the store with third-party capabilities such as middleware, * time travel, persistence, etc. The only store enhancer that ships with Redux * is `applyMiddleware()`. * * @returns {Store} A Redux store that lets you read the state, dispatch actions * and subscribe to changes. */ };function createStore(reducer, preloadedState, enhancer) { var _ref2; if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') { enhancer = preloadedState; preloadedState = undefined; } if (typeof enhancer !== 'undefined') { if (typeof enhancer !== 'function') { throw new Error('Expected the enhancer to be a function.'); } return enhancer(createStore)(reducer, preloadedState); } if (typeof reducer !== 'function') { throw new Error('Expected the reducer to be a function.'); } var currentReducer = reducer; var currentState = preloadedState; var currentListeners = []; var nextListeners = currentListeners; var isDispatching = false; function ensureCanMutateNextListeners() { if (nextListeners === currentListeners) { nextListeners = currentListeners.slice(); } } /** * Reads the state tree managed by the store. * * @returns {any} The current state tree of your application. */ function getState() { return currentState; } /** * Adds a change listener. It will be called any time an action is dispatched, * and some part of the state tree may potentially have changed. You may then * call `getState()` to read the current state tree inside the callback. * * You may call `dispatch()` from a change listener, with the following * caveats: * * 1. The subscriptions are snapshotted just before every `dispatch()` call. * If you subscribe or unsubscribe while the listeners are being invoked, this * will not have any effect on the `dispatch()` that is currently in progress. * However, the next `dispatch()` call, whether nested or not, will use a more * recent snapshot of the subscription list. * * 2. The listener should not expect to see all state changes, as the state * might have been updated multiple times during a nested `dispatch()` before * the listener is called. It is, however, guaranteed that all subscribers * registered before the `dispatch()` started will be called with the latest * state by the time it exits. * * @param {Function} listener A callback to be invoked on every dispatch. * @returns {Function} A function to remove this change listener. */ function subscribe(listener) { if (typeof listener !== 'function') { throw new Error('Expected listener to be a function.'); } var isSubscribed = true; ensureCanMutateNextListeners(); nextListeners.push(listener); return function unsubscribe() { if (!isSubscribed) { return; } isSubscribed = false; ensureCanMutateNextListeners(); var index = nextListeners.indexOf(listener); nextListeners.splice(index, 1); }; } /** * Dispatches an action. It is the only way to trigger a state change. * * The `reducer` function, used to create the store, will be called with the * current state tree and the given `action`. Its return value will * be considered the **next** state of the tree, and the change listeners * will be notified. * * The base implementation only supports plain object actions. If you want to * dispatch a Promise, an Observable, a thunk, or something else, you need to * wrap your store creating function into the corresponding middleware. For * example, see the documentation for the `redux-thunk` package. Even the * middleware will eventually dispatch plain object actions using this method. * * @param {Object} action A plain object representing “what changed”. It is * a good idea to keep actions serializable so you can record and replay user * sessions, or use the time travelling `redux-devtools`. An action must have * a `type` property which may not be `undefined`. It is a good idea to use * string constants for action types. * * @returns {Object} For convenience, the same action object you dispatched. * * Note that, if you use a custom middleware, it may wrap `dispatch()` to * return something else (for example, a Promise you can await). */ function dispatch(action) { if (!isPlainObject(action)) { throw new Error('Actions must be plain objects. ' + 'Use custom middleware for async actions.'); } if (typeof action.type === 'undefined') { throw new Error('Actions may not have an undefined "type" property. ' + 'Have you misspelled a constant?'); } if (isDispatching) { throw new Error('Reducers may not dispatch actions.'); } try { isDispatching = true; currentState = currentReducer(currentState, action); } finally { isDispatching = false; } var listeners = currentListeners = nextListeners; for (var i = 0; i < listeners.length; i++) { var listener = listeners[i]; listener(); } return action; } /** * Replaces the reducer currently used by the store to calculate the state. * * You might need this if your app implements code splitting and you want to * load some of the reducers dynamically. You might also need this if you * implement a hot reloading mechanism for Redux. * * @param {Function} nextReducer The reducer for the store to use instead. * @returns {void} */ function replaceReducer(nextReducer) { if (typeof nextReducer !== 'function') { throw new Error('Expected the nextReducer to be a function.'); } currentReducer = nextReducer; dispatch({ type: ActionTypes.INIT }); } /** * Interoperability point for observable/reactive libraries. * @returns {observable} A minimal observable of state changes. * For more information, see the observable proposal: * https://github.com/tc39/proposal-observable */ function observable() { var _ref; var outerSubscribe = subscribe; return _ref = { /** * The minimal observable subscription method. * @param {Object} observer Any object that can be used as an observer. * The observer object should have a `next` method. * @returns {subscription} An object with an `unsubscribe` method that can * be used to unsubscribe the observable from the store, and prevent further * emission of values from the observable. */ subscribe: function subscribe(observer) { if (typeof observer !== 'object') { throw new TypeError('Expected the observer to be an object.'); } function observeState() { if (observer.next) { observer.next(getState()); } } observeState(); var unsubscribe = outerSubscribe(observeState); return { unsubscribe: unsubscribe }; } }, _ref[result] = function () { return this; }, _ref; } // When a store is created, an "INIT" action is dispatched so that every // reducer returns their initial state. This effectively populates // the initial state tree. dispatch({ type: ActionTypes.INIT }); return _ref2 = { dispatch: dispatch, subscribe: subscribe, getState: getState, replaceReducer: replaceReducer }, _ref2[result] = observable, _ref2; } /** * Prints a warning in the console if it exists. * * @param {String} message The warning message. * @returns {void} */ function warning(message) { /* eslint-disable no-console */ if (typeof console !== 'undefined' && typeof console.error === 'function') { console.error(message); } /* eslint-enable no-console */ try { // This error was thrown as a convenience so that if you enable // "break on all exceptions" in your console, // it would pause the execution at this line. throw new Error(message); /* eslint-disable no-empty */ } catch (e) {} /* eslint-enable no-empty */ } /** * Composes single-argument functions from right to left. The rightmost * function can take multiple arguments as it provides the signature for * the resulting composite function. * * @param {...Function} funcs The functions to compose. * @returns {Function} A function obtained by composing the argument functions * from right to left. For example, compose(f, g, h) is identical to doing * (...args) => f(g(h(...args))). */ /* * This is a dummy function to check if the function name has been altered by minification. * If the function has been minified and NODE_ENV !== 'production', warn the user. */ function isCrushed() {} if ("production" !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') { warning('You are currently using minified code outside of NODE_ENV === \'production\'. ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) ' + 'to ensure you have the correct code for your production build.'); } /** * @class ModuleManager * @category core * @param {Object} object handler * @description Solves modules dependencies * @memberof module:core */ var ModuleManager = function () { function ModuleManager(object) { classCallCheck(this, ModuleManager); this.handler = object; this.currentModule = null; this.store = createStore(function () { var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [{}, '']; var action = arguments[1]; state[0][action.key] = action.data; state[1] = action.key; return state; }); this.modules = {}; } /** * @method active * @instance * @description Sets .currentModule to provided module. * @param {Object} module the module to make current * @memberof module:core.ModuleManager */ createClass(ModuleManager, [{ key: 'active', value: function active(module) { this.currentModule = module; } /** * @method reset * @instance * @description Set's .currentModule to null. * @memberof module:core.ModuleManager */ }, { key: 'reset', value: function reset() { this.currentModule = null; } /** * @method define * @instance * @description Define the module in manager * @param name The module name * @memberof module:core.ModuleManager */ }, { key: 'define', value: function define(name) { this.modules[name] = this.currentModule; } /** * @method use * @instance * @description Get the defined module from manager * @param name The module name * @memberof module:core.ModuleManager */ }, { key: 'use', value: function use(name) { return this.modules[name]; } /** * @method set * @instance * @description An alias for .add() <br/><br/> * Use this method if you know that you will overwrite existing dependency.<br/> * Use it in your app, but not in module that you provide to other people. * @param {String} key the key of the dependency * @param {Object} data the value of the dependency * @memberof module:core.ModuleManager */ }, { key: 'set', value: function set$$1(key, data) { this.store.dispatch({ type: 'ADD', key: key, data: data }); } /** * @method get * @instance * @description Returns dependency in store object, by key. * @param {String} key the key of the dependency * @memberof module:core.ModuleManager * @return {Object|Module} * @throws {DependencyError} if dependency is not in the store * @example <caption>Get the 'hello' dependency</caption> * manager.get('hello'); // -> {world: true} */ }, { key: 'get', value: function get$$1(key) { if (!this.store.getState()[0][key]) { throw new DependencyError('ModuleManager', 'Module requires \'' + key + '\' dependency', this.currentModule); } return this.store.getState()[0][key]; } /** * @method has * @instance * @description Returns whether manager has a dependency with the given key * @param {String} key the key of the dependency * @memberof module:core.ModuleManager * @return {Boolean} Promise that is resolved when all promises completed. * @example <caption>Check whether the store has the 'hello' dependency</caption> * manager.has('hello'); // -> true */ }, { key: 'has', value: function has(key) { return Boolean(this.store.getState()[0][key]); } /** * @method update * @instance * @description Updates deps * @param {Object} [depsMap={}] * @memberof module:core.ModuleManager */ }, { key: 'update', value: function update() { var _this = this; var depsMap = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; this.store.subscribe(function () { var _store$getState = _this.store.getState(), _store$getState2 = slicedToArray(_store$getState, 2), data = _store$getState2[0], changedKey = _store$getState2[1]; var callback = depsMap[changedKey]; if (callback) callback(data[changedKey]); }); } /** * @method add * @alias module:core.ModuleManager#set * @memberof module:core.ModuleManager */ }, { key: 'add', value: function add() { console.warn('.add() method is deprecated. Use .set() instead'); return this.set.apply(this, arguments); } /** * @method require * @instance * @description Require module * @param {String} name Defined name * @param {Function} moduleExecutor Function that returns applied module * @memberof module:core.ModuleManager */ }, { key: 'require', value: function require(name, moduleExecutor) { if (this.use(name) === undefined) this.handler.applyModule(moduleExecutor()); } }]); return ModuleManager; }(); var _class; var _temp; /** * @class Component * @category core * @param {Object} [params] - The parameters object. * @param {Object} [instructions] - The instructions object. * @extends ModuleSystem * @memberof module:core */ var Component = (_temp = _class = function (_ModuleSystem) { inherits(Component, _ModuleSystem); // For keeping children components; // Collection of promises; /** * Collection of `modules`. * @member {Array} module:core.Component#modules * @public */ /** * Static instructions * @member {Object} module:core.Component#instructions * @static * @default {} */ function Component() { var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var defaults$$1 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Component.defaults; var instructions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : Component.instructions; classCallCheck(this, Component); // Apply polyfilled parameters to .params; var _this = possibleConstructorReturn(this, (Component.__proto__ || Object.getPrototypeOf(Component)).call(this)); _this._wait = []; _this.modules = []; _this.children = []; _this.params = extend(transformData(params, instructions), defaults$$1); if (_this.params.manager) _this.manager = new ModuleManager(_this); _this.modules = _this.params.modules; _this.integrateModules(); return _this; } /** * @method wait * @instance * @description Wait for a promise. * @param {Promise} [promise] - The promise that should be added to a queue. * @return {Promise} Promise that is resolved when all promises completed. * @memberof module:core.Component */ // Collection of modules; /** * Collection of `child` Components. * @member {Array} module:core.Component#children * @public */ /** * Array of promises that should be resolved before Component is ready. * @member {Array} module:core.Component#_wait * @private */ /** * Default values for parameters * @member {Object} module:core.Component#defaults * @static * @default { * modules: [], * manager: true * } */ createClass(Component, [{ key: 'wait', value: function wait(promise) { if (promise) this._wait.push(promise); return Promise.all(this._wait); } /** * @method defer * @instance * @description Execute `func` (Callback) when Component is ready. * @param {Function} func - Callback. * @memberof module:core.Component */ }, { key: 'defer', value: function defer(func) { var _this2 = this; if (this.isDeffered) this.wait().then(function () { return func(_this2); });else func(this); } // PARAMETERS /** * @method updateParams * @instance * @description Updates parameters of the Component. * @return {Object} Params of this Component * @memberof module:core.Component */ }, { key: 'updateParams', value: function updateParams() { var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; this.params = extend(params, this.params); return this.params; } // COPYING & CLONING /** * @method clone * @instance * @description Clone this component * @return {object} a cloned component with all its source component' params copied. * @memberof module:core.Component */ }, { key: 'clone', value: function clone() { return new this.constructor(this.params).copy(this); } /** * @method copy * @instance * @description Copy source native and integrate `modules` to it. * @param {Component} source - Source component that is used for `copy()` action. * @param {Function} [customize] - Callback executed before modules integration process. * @return {this} Component * @memberof module:core.Component */ }, { key: 'copy', value: function copy(source, customize) { this.params = _extends({}, source.params); if (source.native) this.native = source.native.clone(source.params); if (customize) customize(); this.integrateModules(source); return this; } /** * @method add * @instance * @description Add a child `Component`. * @param {Component} object - Component that should be added as a `child`. * @return {Promise} Resolved when action is done. * @memberof module:core.Component */ }, { key: 'add', value: function add(object) { var _this3 = this; object.parent = this; return new Promise(function (resolve, reject) { _this3.defer(function () { object.defer(function () { var native = object.native; if (!native) reject(); var addPromise = _this3.applyBridge({ onAdd: object }).onAdd; var resolver = function resolver() { _this3.native.add(native); _this3.children.push(object); resolve(object); }; if (addPromise instanceof Promise) addPromise.then(resolver);else resolver(); }); }); }); } /** * @method remove * @instance * @description Remove a child `Component`. * @param {Component} object - Component that should be a **child** of this Component. * @memberof module:core.Component */ }, { key: 'remove', value: function remove(object) { object.parent = null; this.native.remove(object.native); } /** * @method addTo * @instance * @description Adds `this` Component to specified `App`/`Component`. * @param {Component} object - Component that will be a parent of `this`. * @memberof module:core.Component */ }, { key: 'addTo', value: function addTo(object) { return object.add(this); } }, { key: 'get', value: function get$$1(key) { return this.manager.get(key); } }, { key: 'use', value: function use(key) { return this.manager.use(key); } /** * Returns whether the object is `async` (`wait` promises are more than `0`). * @member {Boolean} module:core.Component#isDeffered */ }, { key: 'isDeffered', get: function get$$1() { return this._wait.length > 0; } /** * Returns the `ModuleManager` used for this component. * @member {ModuleManager} module:core.Component#manager * @throws {ManagerError} */ }, { key: 'manager', get: function get$$1() { if (this._manager) return this._manager; throw new ManagerError('Component', 'ModuleManager is not used in this component. \'manager\' parameter should be set as \'true\'', this); }, set: function set$$1(manager) { this._manager = manager; } /** * Returns the `native` object used for this component. * @member {Object} module:core.Component#native */ }, { key: 'native', get: function get$$1() { return this._native; }, set: function set$$1(mesh) { this._native = mesh; this._native.component = this; return this._native; } }]); return Component; }(ModuleSystem), _class.defaults = { modules: null, manager: true }, _class.instructions = {}, _temp); function attributes() { for (var _len = arguments.length, mappers = Array(_len), _key = 0; _key < _len; _key++) { mappers[_key] = arguments[_key]; } return function (target) { for (var i = 0; i < mappers.length; i++) { var mapper = mappers[i]; for (var k = 0; k < mapper.map.length; k++) { var attribute = mapper.map[k]; Object.defineProperty(target.prototype, attribute, { get: mapper.getter(attribute), set: mapper.setter(attribute), configurable: mapper.configurable, enumerable: mapper.enumerable }); } } }; } function copy() { for (var _len2 = arguments.length, map = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { map[_key2] = arguments[_key2]; } return { map: map, getter: function getter(name) { return function () { return this.native[name]; }; }, setter: function setter(name) { return function (value) { this.native[name].copy(value); }; }, configurable: true, enumerable: true }; } function mirror() { for (var _len3 = arguments.length, map = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { map[_key3] = arguments[_key3]; } return { map: map, getter: function getter(name) { return function () { return this.native[name]; }; }, setter: function setter(name) { return function (value) { this.native[name] = value; }; }, configurable: true, enumerable: true }; } var _dec; var _class$1; var _class2; var _temp$1; /** * @class MeshComponent * @category core * @param {Object} [params] - The parameters object. * @param {Object} [instructions] - The instructions object. * @extends module:core.Component * @memberof module:core */ var MeshComponent = (_dec = attributes(copy('position', 'rotation', 'quaternion', 'scale'), mirror('material', 'geometry')), _dec(_class$1 = (_temp$1 = _class2 = function (_Component) { inherits(MeshComponent, _Component); createClass(MeshComponent, null, [{ key: 'custom', // CUSTOM GEOMETRY HANDLING /** * Default values for parameters * @member {Object} module:core.MeshComponent#defaults * @static * @default * { * build: true, * geometry: {}, * material: false, * * shadow: { * cast: true, * receive: true * }, * * position: {x: 0, y: 0, z: 0}, * rotation: {x: 0, y: 0, z: 0}, * scale: {x: 1, y: 1, z: 1} * } */ value: function custom(geom) { var constructor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : three.Mesh; return function (_MeshComponent) { inherits(_class3, _MeshComponent); function _class3() { classCallCheck(this, _class3); return possibleConstructorReturn(this, (_class3.__proto__ || Object.getPrototypeOf(_class3)).apply(this, arguments)); } createClass(_class3, [{ key: 'build', value: function build() { var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.params; var _applyBridge = this.applyBridge({ geometry: geom, material: params.material }), geometry = _applyBridge.geometry, material = _applyBridge.material; return this.applyBridge({ mesh: new constructor(geometry, material) }).mesh; } }]); return _class3; }(MeshComponent); } /** * Static instructions * @member {Object} module:core.MeshComponent#instructions * @static * @default * { * position: ['x', 'y', 'z'], * rotation: ['x', 'y', 'z'], * scale: ['x', 'y', 'z'] * } */ }, { key: 'create', value: function create(geom, params, constructor) { return new (MeshComponent.custom(geom, constructor))(params); } }, { key: 'from', value: function from(mesh) { var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; params.build = false; var component = new MeshComponent(params); component.native = mesh; component.wrap(); return component; } }]); function MeshComponent(params) { var defaults$$1 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : MeshComponent.defaults; var instructions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : MeshComponent.instructions; classCallCheck(this, Mesh